Code Structure
About
For all projects created on or after 01-06-2025, KendirStudios will adhere to the Official Unity C# Coding Style.
A more detailed explanation can be found in the ebook below.
Cheatsheet
Variables
public int MyVariable;
public int ObjectID { get; }
private int m_myVariable;
public const int k_MyVariable;
private const int k_MyVariable;
public static int s_MyVariable;
private static int s_MyVariable;
Enums
public enum WeaponType
{
Knife,
Gun,
RocketLauncher,
BFG
}
public enum FireMode
{
None = 0,
Single = 5,
Burst = 7,
Auto = 8,
}
[Flags]
public enum AttackModes
{
// Decimal // Binary
None = 0, // 000000
Melee = 1, // 000001
Ranged = 2, // 000010
Special = 4, // 000100
}
Event Args
public struct CustomEventArgs
{
public int ObjectID { get; }
public Color Color { get; }
public CustomEventArgs(int objectId, Color color)
{
this.ObjectID = objectId;
this.Color = color;
}
}
Namespaces
namespace Enemy
Structs
public struct PlayerStats
{
public int MovementSpeed;
public int HitPoints;
public bool HasHealthPotion;
}
Formatting
Properties
public class PlayerHealth
{
// the private backing field
private int m_maxHealth;
// read-only, returns backing field
public int MaxHealth => m_maxHealth;
// equivalent to:
// public int MaxHealth { get; private set; }
}
Use properties on basic get/set operations. On complex logic use methods instead.
public class PlayerHealth
{
private int m_maxHealth;
public int GetMaxHealth
{
return m_maxHealth;
}
}
Brace or indentation style
Use
void DisplayMouseCursor(bool showMouse)
{
if (!showMouse)
{
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
else
{
Cursor.lockState = CursorLockMode.None;
Cursor.visible = true;
}
}
Avoid
void DisplayMouseCursor(bool showMouse){
if (!showMouse) {
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
else {
Cursor.lockState = CursorLockMode.None;
Cursor.visible = true;
}
}
Use
// EXAMPLE: keep braces for clarity...
for (int i = 0; i < 100; i++) { DoSomething(i); }
// … and/or keep the clause on a separate line.
for (int i = 0; i < 100; i++)
{
DoSomething(i);
}
Avoid
for (int i = 0; i < 100; i++) DoSomething(i);
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++)
ExampleAction();
Horizontal spacing
// EXAMPLE: add spaces to make lines easier to read
for (int i = 0; i < 100; i++) { DoSomething(i); }
// AVOID: no spaces
for(inti=0;i<100;i++){DoSomething(i);}
// EXAMPLE: single space after comma between arguments
CollectItem(myObject, 0, 1);
// AVOID: leaving out spacing
CollectItem(myObject,0,1);
// EXAMPLE: no space after the parenthesis and function arguments
DropPowerUp(myPrefab, 0, 1);
//AVOID:
DropPowerUp( myPrefab, 0, 1 );
// EXAMPLE: omit spaces between a function name and parenthesis.
DoSomething()
// AVOID
DoSomething ()
// EXAMPLE: omit spaces inside brackets
x = dataArray[index];
// AVOID
x = dataArray[ index ];
// EXAMPLE: space before condition; separate parentheses with a space.
while (x == y)
// AVOID
while(x==y)
// EXAMPLE: space before condition; separate parentheses with a space.
if (x == y)
// AVOID
if (x==y)
// EXAMPLE: One space between type and name
public float Speed = 12f;
public float Gravity = -10f;
public float JumpHeight = 2f;
public Transform GroundCheck;
public float GroundDistance = 0.4f;
public LayerMask GroundMask;
// AVOID: column alignment
public float Speed = 12f;
public float Gravity = -10f;
public float JumpHeight = 2f;
public Transform GroundCheck;
public float GroundDistance = 0.4f;
public LayerMask GroundMask;
Classes
Organize scripts with this structure:
— Fields
— Properties
— Events / Delegates
— Monobehaviour Methods (Awake, Start, OnEnable, OnDisable, OnDestroy, etc.)
— Public Methods
— Private Methods
Methods
// EXAMPLE: Define an extension method
public static class TransformExtensions
{
public static void ResetTransformation(this Transform transform)
{
transform.position = Vector3.zero;
transform.localRotation = Quaternion.identity;
transform.localScale = Vector3.one;
}
}
// EXAMPLE: Calling the extension method
public class ResetOnStart : MonoBehaviour
{
void Start()
{
transform.ResetTransformation();
}
}
DRY principle: Don't repeat yourself
I'm looking at you Heitor
// DON'T
// EXAMPLE: WRITE EVERYTHING TWICE
private void PlayExplosionA(Vector3 hitPosition)
{
explosionA.transform.position = hitPosition;
explosionA.Stop();
explosionA.Play();
AudioSource.PlayClipAtPoint(soundA, hitPosition);
}
private void PlayExplosionB(Vector3 hitPosition)
{
explosionB.transform.position = hitPosition;
explosionB.Stop();
explosionB.Play();
AudioSource.PlayClipAtPoint(soundB, hitPosition);
}
// USE THIS INSTEAD!
private void PlayFXWithSound(ParticleSystem particle, AudioClip
clip, Vector3 hitPosition)
{
particle.transform.position = hitPosition;
particle.Stop();
particle.Play();
AudioSource.PlayClipAtPoint(clip, hitPosition);
}