- 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
MonoBehaviorunless 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
constfield 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:
privateconstfloatemergencyThreshold=0.25f;
...if(player.health<=emergencyThreshold){ActivateEmergencyItem();}- All
publicvariables and methods should be named in PascalCase. - All
privateandprotectedvariables and methods should be named in camelCase.
- Avoid using abbreviation at all cost. No
evariable forelement, orrbforrigidbody(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(elementeinarray){
...}Do not write it like Go coding syntax or your usual JavaScript coding style:
// Don't do any of theseif(condition){
...}else{
...}foreach(elementeinarray){
...}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(elementeinarray1){
...}foreach(elementeinarray2){
...}Classes fields and method should be written in this order:
publicvariables and properties[SerializedField]privateandprotectedvariables (Should write[SerializeField]andprivate ...in separated lines)privateandprotectedvariablespublicmethodsprivateandprotectedmethods
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()
publicclassSomeClass{publicintSomeInt1=>someInt1
public bool IsSomeStatus {get; private set;}// Don't forget new line hereprotectedfloatsomeFloat=0.24f[SerializeField]privateintadjustableInt=20;[SerializeField]privatefloatadjustableFloat=1.0f;privateintsomeInt1;privateintsomeInt2;publicvoidSomePublicMethod(){}protectedintSomeProtectedMethod(){return0;}// ALWAYS add private access modifier in front of every private methodsprivatevoidStart(){}privatestringSomePrivateMethod(){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 thisprivateintage=10;publicintGetAge(){returnthis.age;}privatevoidSetAge(intage){this.age=age;}Using C# Property (Do this, it's easier and shorter)
publicintAge{get;privateset;}// We access the Age variable by simply call the variable "Age"// Get agecurrentAge=Age;// Set ageAge=ageWeWantToAssign;OR
publicintAge=> age;privateintage=10;// Same way to get, different way to set// Get agecurrentAge=Age;// Set agethis.age=ageWeWantToAssign;Property setter with condition:
publicintAge{get;privateset{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
