Skip to content

Instantly share code, notes, and snippets.

@travelhawk
Last active May 9, 2022 09:36
Show Gist options
  • Save travelhawk/95c9810fb524301738ec7a442b7713cf to your computer and use it in GitHub Desktop.
Save travelhawk/95c9810fb524301738ec7a442b7713cf to your computer and use it in GitHub Desktop.
Code Convention for Unity using C#

Code Conventions C#

Formating

Namespaces & Classes

Casing: PascalCase

public namespace Company.Product.Module
{
  public class SomeClass : MonoBehaviour
  {
  }
}

Methods

Casing: PascalCase

public void SomeMethod()
{
}

Public Fields & Properties (Getter / Setter)

Casing: PascalCase

public int Charisma;
public int Health { get; private set; }

Private Fields

Casing: camelCase

private int health;

Parameters

Casing: camelCase

public void SomeMethod(int someParameter)
{
}

Local Variables

Casing: camelCase

...
int counter = 1;
...

Best practices

  • Minimize dependencies
    • e.g. Instead of direct calls, often events can be used like HealthChanged (use Action or UnityEvent)
  • Not all classes need to be MonoBehaviours (which needs to be attached to a GameObject in the scene)
    • Plain C# classes are more portable than classes which are based on the Unity platform and engine code
  • Define interfaces for exchangeable classes
    • Interfaces also help to be aware of which part of a class is exposed to the outside and which not
  • Use runtime assertions to formulate assumptions and method preconditions which can help to detect bugs early
    • e.g. Assert.IsNotNull(obj) or Assert.IsTrue(condition)
  • Write unit tests to ensure correct behaviour
  • Avoid the overuse of events wired inside the inspector
    • Renaming and other operations can loose link between components
    • Hard to track down and hard to debug

Inspectable fields

There are two ways: make the fields public, or make them private and mark them as [SerializeField]. We decide for the second option because it is tempting to change this public fields by script. Therefore, making it private and deciding when to expose methods or fields to the outside is more precise about the public interface of a component.

// private field which is exposed inside the inspector
[SerializeField]
private int count;

// properties can be used to expose private fields
public int Count { get { return count; }, private set; }

If a field should be exposed and indeed be part of the public interface, the use of public fields is fine.

Performance Considerations

  • Avoid heavy calculations in Update() (runs every frame)
  • Avoid unnecessary assignments of local variables in Update() (garbage collector will run every frame)
    • e.g. Instead of calling obj.GetComponent() in Update(), cache the components you want to access
  • Remove MonoBehaviour methods like Start(), Update() if not needed
  • Avoid overuse of GameObject.Find(), GameObject.FindObjectOfType<T>() as it traverses the whole scene
  • Use profiling after heavy code changes to avoid performance bottlenecks (lookout for spikes)

Resources

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment