Unity C# Coding Conventions & Best Practices

.This guide outlines standard naming conventions, member ordering, and Unity-specific coding practices to help maintain clean, consistent, and scalable code across Unity projects.


1 โœ… Naming Conventions

This is the first and the foremost thing you should improve in your code. This alone holds the power to make your code look organised and professional.

๐Ÿ”น Class, Interface, and Enum Names

  • Use PascalCase
public class GameManager {}
public interface IInteractable {}
public enum WeaponType { Sword, Bow, Gun }

๐Ÿ”น Fields

  • Private fields: camelCase with _ prefix (which I do not prefer or recommend due to its ugly look and unnecessary effort in finding a variable when coding; so, I simply use camelCase without the underscore)

  • Public fields: PascalCase

  • Constants: ALL_CAPS_SNAKE_CASE

[SerializeField] private float _movementSpeed;
public string PlayerName;
private const int MAX_LIVES = 3;

๐Ÿ”น Methods

  • Use PascalCase for all method names
public void TakeDamage(int amount) {}

๐Ÿ”น Local Variables & Parameters

  • Use camelCase
void Move(float speed)
{
    float adjustedSpeed = speed * 2f;
}

๐Ÿ”น Properties

  • Use PascalCase, and expose only when necessary
public int Health { get; private set; }

2 ๐Ÿงฑ Member Ordering (Inside a Class)

This one is more on the beautification side but beautiful_code = readable_code๐Ÿ’ก

Organize class members in the following order:

Member TypeOrder Description
Constants1๏ธโƒฃ At the top
Static Fields / Methods2๏ธโƒฃ Immediately after constants
Instance Variables3๏ธโƒฃ Public โ†’ Protected โ†’ Private
Unity Methods4๏ธโƒฃ Awake, Start, Update, etc.
Public Methods5๏ธโƒฃ Methods exposed to other classes
Protected Methods6๏ธโƒฃ Meant to be overridden in subclasses
Private Methods7๏ธโƒฃ Internal logic
Coroutines / Handlers8๏ธโƒฃ Bottom of the class

๐Ÿงช Example

public class PlayerController : MonoBehaviour
{
    // 1. Constants
    private const float Gravity = 9.81f;

    // 2. Static Fields and Methods
    private static int _globalScore;
    public static void ResetScore()
    {
        _globalScore = 0;
    }

    // 3. Instance Fields
    public float speed;
    protected Rigidbody rb;
    [SerializeField] private int _health;
    private bool _isAlive;

    // 4. Unity Event Methods
    private void Awake()
    {
        rb = GetComponent<Rigidbody>();
    }

    private void Start()
    {
        _health = 100;
        _isAlive = true;
    }

    private void Update()
    {
        Move();
    }

    // 5. Public Methods
    public void TakeDamage(int amount)
    {
        _health -= amount;
        if (_health <= 0) Die();
    }

    // 6. Protected Methods
    protected virtual void Die()
    {
        _isAlive = false;
    }

    // 7. Private Methods
    private void Move()
    {
        rb.velocity = new Vector3(Input.GetAxis("Horizontal") * speed, rb.velocity.y, 0);
    }

    private bool IsAlive()
    {
        return _isAlive;
    }

    // 8. Coroutines / Event Handlers
    private IEnumerator FadeOut()
    {
        yield return new WaitForSeconds(1f);
    }
}

3 ๐Ÿ” Access Modifiers

  • Always declare your variables and functions with access modifiers (public, private, protected, internal)

  • Prefer private fields and expose them through public properties or [SerializeField]

  • Avoid public fields unless absolutely necessary

[SerializeField] private int _ammoCount;
public int AmmoCount => _ammoCount;

4 โœ๏ธ Formatting & Style

๐Ÿ”น Braces

  • Use Allman style: braces go on a new line
if (isActive)
{
    Activate();
}

๐Ÿ”น Variable Declarations

  • One variable per line
private int _score;
private float _speed;

๐Ÿ”น Spacing

  • Add blank lines between logical code blocks and method definitions

For example, if you have a Jump() method and jumpForce variable, keep them near each other. You can also use #region in C# to logically group related code. This is especially helpful when your code stretches for 100s of lines which it will when following all these formatting standards.

#region Jump

[SerializeField] private float jumpForce;
private void Jump() { ... }

#endregion

5 ๐Ÿ—‚๏ธ File Structure & Namespaces

  • One public class per file

  • File name should match the class name exactly

  • Use namespaces to reflect folder hierarchy and logical organization (needed for larger codebases where your class names might conflict with Unityโ€™s classes)

namespace Game.Enemies.Bosses
{
    public class DragonBoss {}
}

๐Ÿ”—Refer this super informative blog for more in-depth guidelines.

0
Subscribe to my newsletter

Read articles from Mohammad Asim Khan directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Mohammad Asim Khan
Mohammad Asim Khan