Unity Term Book
Scripting & Lifecycle

Awake & Start

Awake runs when the object is created (even if disabled); Start runs on the first enabled frame — after every Awake in the scene has finished. Know this order.

Imagine...

Awake is personal prep before work — get dressed, grab the keys, no one else involved. Start is the morning kickoff meeting — everyone is already present (all Awakes finished), so you can assign cross-team work (GameManager.Instance, find other objects…).

The concept in detail

Awake() is called exactly once when the instance is created — even if the component has enabled = false. Ideal for internal refs: _rb = GetComponent<Rigidbody>().

Start() runs on the first frame after the component is enabled. Because every Awake() in the scene has already run, Start is safe for Singletons, finding other objects, or registering events. If you disable then re-enable, Start does not run again.

Execution order: Unity runs Awake on all scripts first, then Start on all scripts. Order between scripts is undefined unless you set Script Execution Order in Project Settings.

Runtime Instantiate: spawned objects also get Awake + Start. Awake runs before Instantiate() returns; Start runs at the start of the next frame.

Execution order across scripts

⚡ AWAKE phase (before the first frame)

GameManager.Awake()

_instance = this

PlayerCtrl.Awake()

_rb = GetComponent()

EnemyAI.Awake()

_nav = GetComponent()

🚀 START phase (first frame)

GameManager.Start()

LoadLevel(1)

PlayerCtrl.Start()

GameManager.Instance ✅

EnemyAI.Start()

FindPlayer() ✅

🔄 Update Loop (every frame)

Hands-on steps

1

Awake: self-initialize

Cache GetComponent<T>(), init private fields, set up Singletons. Do not call other objects.

2

Start: connect to the outside world

Use GameManager.Instance, FindObjectOfType<T>(), register events.

3

Use Script Execution Order when needed

Edit → Project Settings → Script Execution Order → drag a script higher so it runs earlier.

4

Avoid cross-script nulls

If ScriptA.Awake touches ScriptB (not Awake yet), you get null. Reach across scripts in Start.

Interactive simulator

Add scripts to the scene and press Load Scene to watch Awake then Start fire for each one.

Scripts in Scene

Execution Log

Add scripts, then Load Scene...

Phase: Idle|Add at least 2 scripts and press Load Scene

Code example

Basic

Singleton pattern in Awake; other components connect in Start.

public class GameManager : MonoBehaviour
{
  public static GameManager Instance { get; private set; }

  void Awake()
  {
      // Singleton setup — runs before every Start()
      if (Instance != null) { Destroy(gameObject); return; }
      Instance = this;
      DontDestroyOnLoad(gameObject);
  }
}

public class PlayerController : MonoBehaviour
{
  private Rigidbody _rb;

  void Awake() => _rb = GetComponent<Rigidbody>();

  void Start()
  {
      // Safe: GameManager.Awake() already finished
      GameManager.Instance.RegisterPlayer(this);
  }
}

Code example

Advanced

Control Awake order with the [DefaultExecutionOrder] attribute.

using UnityEngine;

// Runs before other scripts (more negative = higher priority)
[DefaultExecutionOrder(-100)]
public class ServiceLocator : MonoBehaviour
{
  public static ServiceLocator Instance { get; private set; }
  private Dictionary<System.Type, MonoBehaviour> _services = new();

  void Awake()
  {
      Instance = this;
      // Auto-register every IService in the scene
      foreach (var svc in FindObjectsOfType<MonoBehaviour>())
          if (svc is IService)
              _services[svc.GetType()] = svc;
  }

  public T Get<T>() where T : MonoBehaviour =>
      _services.TryGetValue(typeof(T), out var s) ? s as T : null;
}

// Any script can fetch a service in Start:
// var gm = ServiceLocator.Instance.Get<GameManager>();

📌 Quick recap

  • Awake: prepare yourself — no one else required
  • Start: connect to the scene — after all Awakes
  • Start does not re-run on enable/disable
  • Use [DefaultExecutionOrder] to lock order

⚠️ Common mistakes

  • ❌ Touching a Singleton inside Awake()

    Singleton may not have Awoken yet → NullReferenceException

    ✅ Access Singletons in Start()

  • ❌ Creating the Singleton in Start()

    Other scripts finish Awake while the Singleton is still missing → null

    ✅ Always create Singletons in Awake()