Skip to content

Code Convention Unity C#

Stanislav Osipov edited this page Sep 10, 2020 · 5 revisions
  • Our standard designed to match Unity package world conventions as closely as possible. For the rules not mentioned here please use Microsoft's Framework Design Guidelines.
  • This document includes a subset of the most used rules
  • If the compiler does not require something, leave it out (i.e. this. prefix, default access levels, Attribute postfix, etc.)
  • If text pr expressions can be minimized, do this. Unless it makes it hard to read/understand, use you own judgment.

IDE Settings

Encoding

  • Text file encoding is UTF8 with no BOM, using LF (unix) line endings.
  • 4-wide tab stops, using spaces only (no tab characters)
  • No trailing whitespace on lines, but always include a single newline at the end of the file.

Files.

  • No file header, copyright, etc. of any kind. Some IDEs may add them automatically - please remove them.
  • Maintain the style of the surrounding code if it has its own separate standard.
  • Use PascalCase for file names, typically matching the name of the dominant type in the file (or if none is dominant, use a reasonable category name).
  • One file -> one type. Only declare more then one type the file if:
    • This is a private type used by the dominant type only.
    • This type is included in the dominant type.

Naming

  • Use PascalCase for all symbol names, except where noted.
  • No Hungarian notation.
  • No prefixes, suffixes, except where noted.
  • Spell words using correct US-English spelling.
  • Avoid abbreviations when possible unless the abbreviation is commonly accepted.
  • Acronyms are PascalCase, unless they are exactly two letters, in which case they are UPPERCASE. (ex. htmlText, GetCpuCycles(), IOStream)

Type Naming

  • Avoid unnecessary prefixes/suffixes
  • Make type names unambiguous across namespaces

Wrapping

  • Wrap code once it gets to around 120 columns wide to keep side-by-side diffs sane (not a hard limit; use your judgment).
  • When necessary, break lines after boolean operators in conditional expressions, after ; in for-statements, and after , in function calls

Blank lines

  • Never put more than one blank line between code.
  • Put exactly one blank line between multi-line methods and properties.
  • Blank line between one-line methods, properties, and files is not required but not forbidden either. Use your own judgment.

Comments

  • Documenting the why is far more important than the what or how.
  • Document anything that would surprise another engineer (or yourself in six months when you've forgotten it).
  • No "divider" comments (i.e. long ----- and ////// comments just to break up code).
  • No "category" comments (i.e. // Functions // Private Data // Globals etc.).
  • Use of #region is always disallowed.
  • Only use /// (triple slash) comments if you are writing xml doc, and never for ordinary comments that you want to stand out

Usings

  • Located at file scope at the top of the file, never within a namespace.
  • Strip unused usings.
  • Only use aliases when required by the compiler for disambiguation. Aliases should be paced in the end of the usings block.

Enums

  • Use a singular type name
  • Do not specify constant values unless absolutely required
  • Trail last element in a list with ,
enum EnumsSample 
{
   First,
   Second,
   Third,
}

Flags enum

Use a plural type name. Use column-aligned bit shift expressions for the constants (instead of 2, 4, 8, etc.)

[Flags]
public enum DirectionOptions
{
    North    = 1 << 0,
    East     = 1 << 1,
    West     = 1 << 2,
    South    = 1 << 3,
}

Interfaces

  • Use I prefix to indicate an interface.
  • Ensure that the names differ only by the I prefix on the interface name when you are defining a class-interface pair, where the class is a standard implementation of the interface
public interface IUnit
{
   float Size { get; }

   void Stop();
   void DoSomething();
}

public class Unit : IUnit 
{
    ...
}

Fields

  • Use PascalCase with no prefix.
  • Use prefix & PascalCase for private field naming.
    • m_ instance field.
    • s_ static read-write field,
    • k_ const or static read-only if intended to be used as constant.
  • Drop redundant initializers (i.e. no = 0, = null, = default;).
  • Drop redundant access specifiers (leave off private at type scope).
  • Use readonly where const isn't possible.
    • static readonly Vector3 k_Direction = Vector3.left;

Events

  • Do not declare new delegate types. Use Action<T> instead.
  • Do not expose public delegate fields. Use events instead.
  • Include one participle-form verb in the event name (generally ending in -ed or -ing, ex. occurred, loading, started, given).
  • If event Action need to pass more then 1 parameter. Consider using struct as an action argument.

Attributes

  • Drop 'Attribute' postfix when applying an attribute.