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() ✅
Hands-on steps
Awake: self-initialize
Cache GetComponent<T>(), init private fields, set up Singletons. Do not call other objects.
Start: connect to the outside world
Use GameManager.Instance, FindObjectOfType<T>(), register events.
Use Script Execution Order when needed
Edit → Project Settings → Script Execution Order → drag a script higher so it runs earlier.
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...
Code example
BasicSingleton 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
AdvancedControl 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()