- make sure game is playable, if not fix it before push or code on your own branch
- if there are conflict, merge it and revisit 1
- Always use emoji at the start of the commit ref: link, link
- Always start with infinitive verb that represent what you have done such as Update... Add... Create... not Added/Adding
Coding Convention ref
To put it simple. It's clean to look at. But in details, here are the reasons I can think of:
- Cleaner code means more scalability, maintainability.
- Easier code to understand. Your teammates are happier to read your code, and are more willing to fix your code if needed.
- Only one standard of coding, no argument over coding styles will ever happen.
- Generally, do not use
MonoBehavior
unless you need to. When do you need to use it? Normally, it's when you useStart()
,Awake()
,Update()
,OnDestroy()
methods. - No magic number in methods. Declare it as
const
field of the class instead Magic number example (don't do this): - A class should try to only serve its purpose (High cohesion). And it should not try to call other classes' functions too much (Less coupling).
if (player.health <= 0.25f) // 0.25f is a magic number
{
ActivateEmergencyItem();
}
Do this instead:
private const float emergencyThreshold = 0.25f;
...
if (player.health <= emergencyThreshold)
{
ActivateEmergencyItem();
}
- All
public
variables and methods should be named in PascalCase. - All
private
andprotected
variables and methods should be named in camelCase.
- Avoid using abbreviation at all cost. No
e
variable forelement
, orrb
forrigidbody
(I know I named that once, I'll fix it). - For any float variable, declare the value with full float number e.g.
3.0f
, not just3
- For any bool variable, pick an associated verb to start with, e.g.
isDragonForm
,hasItem
,canTransform
.
All curly brackets {}
should be in the new line. For example:
if (condition)
{
...
}
else
{
...
}
foreach(element e in array)
{
...
}
Do not write it like Go coding syntax or your usual JavaScript coding style:
// Don't do any of these
if (condition) {
...
}
else {
...
}
foreach(element e in array) {
...
}
After you close curly brackets, leave one new line after it. For a cleaner looking code (except if/else
and try/catch
of course)
foreach(element e in array1)
{
...
}
foreach(element e in array2)
{
...
}
Classes fields and method should be written in this order:
public
variables and properties[SerializedField]
private
andprotected
variables (Should write[SerializeField]
andprivate ...
in separated lines)private
andprotected
variablespublic
methodsprivate
andprotected
methods
For each cluster of variable type (like public, protected, serialized private, private). There should be a new line to separate them as well.
Also, ALWAYS add private access modifier in front of every private methods. Even default generated MonoBehaviour
methods like Start()
or Update()
public class SomeClass
{
public int SomeInt1 => someInt1
public bool IsSomeStatus { get; private set; }
// Don't forget new line here
protected float someFloat = 0.24f
[SerializeField]
private int adjustableInt = 20;
[SerializeField]
private float adjustableFloat = 1.0f;
private int someInt1;
private int someInt2;
public void SomePublicMethod()
{
}
protected int SomeProtectedMethod()
{
return 0;
}
// ALWAYS add private access modifier in front of every private methods
private void Start()
{
}
private string SomePrivateMethod()
{
return "";
}
}
C# Properties are one of the most useful features in C#, but it can be confusing at first. If you wonder when should you use property, I have a simple opinion: When you want to write getters or setters.
Traditional Java getters and setters (Don't do this):
// Don't do this
private int age = 10;
public int GetAge()
{
return this.age;
}
private void SetAge(int age)
{
this.age = age;
}
Using C# Property (Do this, it's easier and shorter)
public int Age { get; private set; }
// We access the Age variable by simply call the variable "Age"
// Get age
currentAge = Age;
// Set age
Age = ageWeWantToAssign;
OR
public int Age => age;
private int age = 10;
// Same way to get, different way to set
// Get age
currentAge = Age;
// Set age
this.age = ageWeWantToAssign;
Property setter with condition:
public int Age
{
get;
private set
{
if (value < 0)
{
value = 0;
}
Age = value;
}
}
We will use order from Visual Studio EditorConfig file which preferred order as below
- access modifiers: { public / private / protected / internal / protected internal / private protected }
- static
- extern
- new
- inheritance modifiers: { virtual / abstract / override / sealed override }
- readonly
- unsafe
- volatile
- async