- PascalCase: public members, methods, constants
- _camelCase: private fields (static or instance)
- PascalCase: public static fields and properties
- camelCase: local variables and parameters
varfor apparent local variables- Target-typed
new()— nevernew TypeName() - Allman-style braces
- Block-scoped namespaces, not file-scoped
- Expression-bodied members for single-line properties/methods, not constructors
nameof()for strings (animation params, events, input actions)- Pattern matching over if-else chains
switchexpression preferred overswitchstatement- Collection/object initializers where applicable
record/readonly structfor data carriers- Prefer static local functions
is null/is not null— never== nullor!= null??=null-coalescing assignment where applicable- Throw expressions:
x ?? throw new InvalidOperationException() sealedon classes not intended for inheritancereadonlyon fields never reassigned after construction
rb.linearVelocitynotrb.velocityFindObjectsByType<T>()notFindObjectsOfType<T>()FindAnyObjectByType<T>()notFindObjectOfType<T>()RaycastNonAllocfor physics queriesTryGetComponent<T>()notGetComponent<T>()when component may be absentCompareTag()not==for tag comparisonPhysics.SyncTransformsnot deprecatedPhysics.autoSyncTransforms- Never use
GameObject.FindorFindWithTag— wire via Inspector or find at init only - New Input System only:
Keyboard.current,Mouse.current— never legacyInputclass - Implicit null check for object:
if (gameObject)/if (!this)— never!= null [SerializeField]private fields + public property with private setter — no raw public fields[DisallowMultipleComponent]on components that must not be duplicated per GameObject- Cache
GetComponentin fields, never inUpdate