Coding standards for Unity 3D C# scripting

Coding standards is set of rules, techniques and best practices create more readable, efficient, consistent code with minimal errors. They offer a uniform format by which software engineers can use to build consistent and highly optimized code. Coding best practices and standards vary depending on the industry a specific product is being built for. The standards required for coding software for constructions will differ from those for coding software for gaming. Adhering to industry-specific standards make it easier to write accurate code that matches product expectations. It becomes easier to write code that will satisfy the end-users and meet business requirements.

As a programmer, It is very important to follow a coding standard and make sure others can read and easily understand his code. While there’s not a majority guideline of coding standard in Unity and C#. This are very few standards that I adopted in development throughout my coding journey.

Always try to follow the standards that mentioned by Unity and C# team.

All similar files should be grouped in the root folders:

Assets
Animations - Animation clips
Editor - Editor specified scripts, prefabs
Fonts - Fonts used in game
Materials - Texture materials
Prefabs - In-game prefabs
Resources - Unity resources assets
Scenes - Scenes
Scripts - Code scripts, grouped in sub-folders
Sounds - Audio clips
Textures - Image textures
UI - Texture used for UI
Icons - App icons

File naming is simple, always use Pascal Case except for images:

  • Folders - PascalCase
  • FolderName/Images - Use hyphen Eg: image-name-32x32.jpg
  • The rest - PascalCase Eg: ScriptName.cs, PrefabName.prefab, SceneName.unity

The reason images use hyphen naming is that most images are also used in website. Hyphen naming is the majority naming convention for web image and it’s also search engine friendly. Using the same name can save us time renaming and easily find the same image switching between Unity and web.

While each script has its unique purpose and use cases, we follow these naming rules and so we can still roughly know what the script is for by simply reading the filenames:

  • XxxCanvas, XxxText, XxxButton - UI
    ChoiceSelector, Shoot, BuyProduct
  • XxxManager - Use only ONE instance in the scene for master scripts
    PlayerController, BossController, BackgroundControler
  • XxxDatabase - for a database which contains a list of data rows
    WeaponDatabase, CardDatabase
  • XxxData - for data row in a CSV database
    UserData, CardData
  • XxxItem - for in-game item instance
    CardItem, CharacterItem
  • XxxGenerator - for scripts instantiate GameObjects
    ObjectGenerator, LandGenerator
  • XxxSettings - for settings scripts inherent Unity’s ScriptableObject class
    AchievementSettings, DailyLoginSettings
  • XxxEditor - for editor-only scripts inherent Unity’s Editor class
    TutorialTaskEditor, AchievementSettingsEditor

Difference between Manager and Controller is Manager should be singleton or static, and it controls a specific game logic that may involve multiple objects and assets, while Controller controls an object and may have multiple instances. For example, there are multiple EnemyController in the scene and each control one enemy.

Similar to file naming, variable naming allow us to know what the variable is for without reading though all code:

  • Use camcelCase, always as of a noun or in a form of adjective.
    hasFinished, currentLocation, isStarted
  • Prefix with an underscore for private and protected variables.
    _itemIndex, _controller, _serialNo
  • All capital letters for constant variables.
    SHOW_MENU_TITLE, TEXT_COUNT, BASE_URL
  • All capital letters and PREFS_XXXX for PlayerPref keys.
    PREFS_USER_SCORE
  • Use xxxPrefab for scene GameObject variables
    vehiclePrefab, coinPrefab
  • Use xxxTF for Transform variables
    userTF, stickTF
  • Use xxxComponent for all other components, abbreviate if needed
    eyesSpriteRenderer / eyesSR, runAnim, attackAC, victoryAC
  • Use xxxxs for arrays
    names, users
  • Use xxxxList for List and xxxxDict for Dictionary
    nameList, userList
  • Use nounVerbed for callback event
    prefabInstantiated, bulletFired
  • Unity use prefix _ for private/protected variables, and s_ for static variables.
  • Use PascalCase - start with a verb and followed by a noun if needed
    Bonus, EndScene, MoveToLeft
  • Use OnXxxxClick - for UI button clicks
    OnStartClick, OnCancelClick
  • Use OnNounVerbed - for callbacks
    OnChestOpened, OnBuyWeaponConfirmed
  • Member Properties
    If a function has no input, use member property in PacelCase
    bool IsRewarded() { }
    to
    bool IsRewarded {get { return …} }
  • Also, use member properties where a variable can only set internally but can be accessed publicly:
    public int Id { get; private set; }
    public Sprite IconSprite { get; private set; }

Having a consistent order can greatly save our time on looking for a specific variable or function:

MyClass : Monobehavior
{
// Constant variables
public const int CONST_1;
private const string CONST_2;
// Static variables
public static int static1;
private static string _static2;

// Editor-assigned variables
[SerializeField] public Image logoImage;
[SerializeField] private MyClass _anotherComponent;
// Other varaibles
public int primitiveVariable1;
private string _primitiveVariable2;
// Properties
public int Property1 {get; set;}
private string _property2 {get; set;}
// Unity functions
Awake()
OnEnable()
Start()
Update()
FixedUpdate()
// Other custom functions
Init()

Reset()
// Unity functions
OnDisable()
OnDestroy()
#region UNITY_EDITOR
// Debug functions that only runs in Editor
[ContextMenu("…")]
private void DebugFunction1()
[MenuItem("Debug/…")]
private static void DebugFunction2()
#endregion
}

You can also group valuables and functions in a region in large scripts.

  • Single line comments should include a space after the slashes:
    // Notice the space after the two slashes
  • Temporarily commenting out code should not include a space after the slashes, to be differentiated from the normal comment:
    //noSpace.Code();
  • TODO comments should include the space after the slashes and then 2 spaces after the colon following the TODO
    // TODO: Notice the space after the slashes and the 2 spaces after the colon of todo

I hope you had fun reading and/or following along. If you are interested in further exploring, here are some resources I found helpful along the way: