Chapter 02
Programming for games
How game code is structured in your engine: the script lifecycle, components, exposed variables, events and the language itself.
Script lifecycle
Also called Awake, _ready, _process, BeginPlay, lifecycle method
- What
- The functions the engine calls on your code at set moments: once when the object is created or enters play, then every frame, then at a fixed physics rate, and finally when it is destroyed.
- Why
- Putting code in the right callback avoids most beginner bugs: setup in the start callback, per-frame logic in update, physics in the fixed-rate callback.
public class Player : MonoBehaviour
{
void Awake() { /* own references */ }
void Start() { /* talk to others */ }
void Update() { /* input, per frame */ }
void FixedUpdate() { /* physics */ }
}Watch out
Reading another object in the earliest callback before it has initialised itself, which gives null references.
Components and composition
Also called ECS, composition over inheritance
- What
- Building game objects from small parts: a health component, a mover, a sprite, a collider. Unity uses components on GameObjects, Godot uses child nodes, Unreal uses Actor Components.
- Why
- Small reusable parts let you make a new enemy by combining existing pieces, instead of a deep class tree where every change breaks something.
Watch out
One giant player script of 2,000 lines that handles input, health, animation, sound and UI.
Exposed variables
Also called SerializeField, @export, UPROPERTY EditAnywhere
- What
- Variables marked so they appear in the editor, where you or a designer can tune them without touching code.
- Why
- Game feel is found by tweaking numbers such as speed, jump height and cooldowns while the game runs. Exposing them makes tuning fast.
[SerializeField] float moveSpeed = 6f;
[SerializeField] int maxHealth = 3;
[SerializeField] GameObject bulletPrefab;Watch out
Changing values in the editor while in play mode and losing them all when you stop.
Events, signals and dispatchers
Also called observer pattern, delegates
- What
- A way for an object to announce that something happened, such as "health changed", so that any number of listeners can react without the sender knowing about them.
- Why
- It keeps code decoupled: the health bar, the sound and the achievement system all listen to the player instead of the player calling each one.
public event System.Action<int> HealthChanged;
void TakeDamage(int amount)
{
health -= amount;
HealthChanged?.Invoke(health);
}Watch out
Forgetting to disconnect or unsubscribe when a listener is destroyed, which causes errors or leaks.
MonoBehaviour and GetComponent
- What
- The base class for Unity scripts that live on GameObjects.
GetComponent<T>()finds another component on the same object, such as itsRigidbody2D. - Why
- Almost all Unity gameplay code is MonoBehaviours talking to each other through components and references set in the Inspector.
Rigidbody2D rb;
void Awake()
{
rb = GetComponent<Rigidbody2D>();
}Watch out
Calling GetComponent or FindObjectOfType every frame in Update instead of caching the result once.
C# essentials for Unity
Also called C# for Unity, Unity C#
- What
- The parts of C# you use daily in Unity: classes, fields and properties, lists and dictionaries, enums, interfaces, events, and
ScriptableObjectfor shared data assets. - Why
- Knowing plain C# well makes Unity code shorter and safer. ScriptableObjects in particular let you keep weapon or enemy stats as assets instead of hard-coded numbers.
Watch out
Making every field public just to see it in the Inspector, when [SerializeField] private does the same job safely.
State machine
Also called FSM, finite state machine
- What
- Modelling an object as one state at a time, such as idle, running, jumping or attacking, with clear rules for moving between states.
- Why
- It replaces a tangle of booleans (
isJumping,isAttacking,isHurt) with one variable, so impossible combinations cannot happen. Enemy AI and animation both use it. - Example
- An enemy patrols until it sees the player, chases while in range, attacks when close, and returns to patrol if the player escapes for three seconds.
Watch out
Adding a new boolean for every behaviour until the player can attack while dead.
Debugging games
Also called logging, breakpoints, debug draw
- What
- Printing values to the console, pausing on breakpoints in your IDE, and drawing debug lines, shapes and text in the game view to see what the code thinks is happening.
- Why
- Game bugs are often visual or timing related, so seeing a ray or a hitbox on screen finds them faster than reading code.
Debug.Log($"Speed {rb.linearVelocity}");
Debug.DrawRay(transform.position,
Vector3.down * 1.1f, Color.red);Watch out
Leaving hundreds of log lines running every frame, which slows the game and hides the message you need.