Lesson 4 - MonoBehaviour Lifecycle (Awake, Start, Update)

Which of your methods Unity calls and in what order: why every Awake finishes before any Start, what belongs in each callback, and how the order explains most null-reference bugs a beginner hits.

Subject: Unity Game Engine · 61 slides · code lesson

Open the interactive version of this deck · Homework for this lesson

What this lesson covers

The lesson, slide by slide

1. The MonoBehaviour Lifecycle

Title

Unity - Lesson 4

You never call these methods. Unity does - in an order worth knowing.

2. What you will be able to do

Objectives

You got the one lifecycle question right in the diagnostic. This lesson goes past it, because lesson 5 leans on the order: most 'it is null' errors are a lifecycle mistake wearing a null-reference costume.

  1. Name the eight callbacks that matter and say what each is for
  2. Explain why every Awake finishes before any Start - and what that buys you
  3. Predict which callbacks run on a disabled component and on an inactive object
  4. Put the right kind of code in the right callback without guessing
  5. Read a frame-stamped lifecycle log and say what the scene did

3. Answer from memory first

Warm-up

Before anything on the next slides.

Discussion prompt

Name every method you can think of that Unity calls on a MonoBehaviour without you calling it. For each, say when you think it runs.

Hint: There are five you will use constantly and three more worth knowing.

Answer:

The five: Awake, Start, Update, FixedUpdate, LateUpdate.

The three: OnEnable, OnDisable, OnDestroy - the pair that brackets being switched off, and the one that runs when the object goes away.

If you named Update and Start only, that is completely normal. The other six are exactly where this lesson pays for itself.

4. The callbacks Unity calls for you

Section

Part 1

5. You write them; Unity calls them

Concept

Figure (svg): The MonoBehaviour lifecycle as a vertical timeline: Awake, OnEnable, Start, then a repeating frame loop, then OnDisable and OnDestroy

You write the methods. Unity decides when they run.

A MonoBehaviour is a component Unity knows how to talk to. If you write a method with one of a handful of exact names, Unity calls it at the matching moment. You never call them yourself.

Callback — A method you write and the engine calls. Unity finds them by exact name - which is why a typo is a silent failure rather than a compile error.

Unity Manual - Order of execution for event functions Order of execution

6. A theatre call sheet

Intuition

Actors do not decide when to walk on. There is a call sheet: everyone in the building first, then everyone in costume, then the curtain goes up, then a scene runs over and over, then the curtain comes down.

Awake is arriving at the theatre. Start is the last check before the curtain. Update is the scene, running once per frame for as long as the show lasts. OnDestroy is leaving the building.

The useful part of the analogy: you do not ask an actor a question while they are still parking the car. That is what reaching for another object in Awake does.

7. The eight worth knowing

Concept

callbackwhenwhat belongs there
Awakeonce, when the object is createdcache your own components, set your own fields
OnEnableafter Awake, and on every re-enablesubscribe to events
Startonce, before the first Updatefind other objects and ask them things
FixedUpdateon the physics clock, ~50/secondforces, velocity, MovePosition
Updateonce per rendered frameinput, timers, game logic
LateUpdateafter every Update this framecamera follow, anything needing final positions
OnDisableon deactivate, and before OnDestroyunsubscribe from events
OnDestroywhen destroyed, or when Play endsrelease anything nothing else will

Learn the first three properly and the rest fall into place - they are all variations on 'when exactly'.

8. A logger that numbers every call

Worked example

Put this on two objects and the Console shows the global order, not just one object's story.

public class LifecycleLogger : MonoBehaviour
{
    static int order;                                  // shared by every instance

    void Log(string callback)
    {
        order++;
        Debug.Log($"{order,3}  {callback,-12} on '{name}'  frame {Time.frameCount}");
    }

    void Awake()     { Log("Awake"); }
    void OnEnable()  { Log("OnEnable"); }
    void Start()     { Log("Start"); }
    void Update()    { Log("Update"); }
    void OnDisable() { Log("OnDisable"); }
    void OnDestroy() { Log("OnDestroy"); }
}

The counter is static, on line 3

Why: One counter shared across every instance. That is what makes the ordering between objects visible - a per-object counter would show 1, 2, 3 on both and prove nothing.

#callbackobjectframe
1AwakeA1
2AwakeB1
3OnEnableA1
4OnEnableB1
5StartA1
6StartB1
7UpdateA1

9. Predict the grouping

Prediction

Three objects, each with that logger, in one scene.

Predict first

Which order does Unity use?

  • A.Awake, A.Start, B.Awake, B.Start, C.Awake, C.Start
  • A.Awake, B.Awake, C.Awake, then A.Start, B.Start, C.Start
  • Whichever order they appear in the Hierarchy, fully one at a time
  • It is random and you cannot rely on it

Correct: Every Awake, then every OnEnable, then every Start.

Why: Unity runs the phases across all objects, not object by object. Which object goes first WITHIN a phase is not guaranteed - but the barrier between phases is, and that guarantee is the entire reason there are two setup callbacks instead of one.

10. Match the job to the callback

Matching

Each of these lines of code belongs in exactly one callback.

Match the pairs

Where does each belong?

  • j1. body = GetComponent<Rigidbody>();
  • j2. player = FindPlayerInTheScene();
  • j3. body.AddForce(thrust);
  • j4. camera.position = target.position + offset;
  • c1. Awake
  • c2. Start
  • c3. FixedUpdate
  • c4. LateUpdate

Why: Your own components in Awake; other objects in Start; physics on the physics clock; camera follow in LateUpdate so it sees the final positions of everything that moved this frame. Putting the camera in Update gives you a camera that lags one frame behind, which reads as jitter.

11. Trap: calling a callback yourself

Trap

The trap

Start does my setup, so if I need to reset the object I will just call it again.

void OnPlayerRespawn()
{
    Start();            // "re-run my setup"
}
  • It compiles, and it half works - which is what makes it dangerous
  • Unity still calls Start once itself, so setup has now run twice
  • Anything that counts, subscribes or spawns in Start now does it twice
  • The next reader cannot tell which Start call they are looking at

The fix

Callbacks are Unity's to call. If setup needs to be repeatable, put it in a method with a name that says so, and call that from Start.

void Start()
{
    ResetForNewLife();
}

void OnPlayerRespawn()
{
    ResetForNewLife();     // same code, deliberately, from both places
}

void ResetForNewLife() { health = 100; isDead = false; }
wantdo
setup that runs onceput it in Awake or Start
setup that can repeata named method, called from the callback
setup on every re-enableOnEnable - Unity already calls it every time

12. Why Awake and Start are two things

Section

Part 2

13. The barrier is the point

Concept

Figure (svg): Two objects A and B showing all Awakes finishing before any Start begins

The barrier between the two phases is the whole reason both exist.

Every Awake in the scene finishes before any Start begins. So code in Awake cannot assume anyone else is ready - and code in Start can assume everyone is.

Build yourself in Awake. Reach for others in Start. That one line prevents the most common startup bug in Unity.

Unity Scripting API - MonoBehaviour.Awake Awake

14. The bug the split prevents

Worked example

Two objects, each wanting a value the other publishes in its own Awake.

public class WhyAwakeThenStart : MonoBehaviour
{
    public WhyAwakeThenStart partner;
    public int myNumber = 7;
    public int Published { get; private set; }

    void Awake()
    {
        Published = myNumber;                 // publish mine
        int seen = partner.Published;         // ...and read theirs. Too early.
    }
}

Line 9 always works

Why: You are writing your own field. Nothing else has to exist for that.

Line 10 works for exactly one of the two objects

Why: Whichever wakes second sees a published value. Whichever wakes first sees 0 - the default, because the partner has not reached line 9 yet.

objectwakesreads partnergets
LeftfirstRight.Published0 - wrong
RightsecondLeft.Published7 - correct, by luck
Left (in Start instead)-Right.Published42 - correct, always
Right (in Start instead)-Left.Published7 - correct, always

15. One PASS, one FAIL, same code

Anomaly

The lab prints this with both objects set to read in Awake.

Predict first

Both objects run identical code. Why does only one of them fail?

  • One of them has a bug in its data
  • Whichever woke first read a partner that had not published yet
  • Unity skips Awake on the second object
  • The FAIL is a false alarm

Correct: Whichever woke first read a partner that had not published yet.

[L04] PASS  'Pair · Right' read 7 from 'Pair · Left' during Awake and got lucky — it woke second
[L04] FAIL  'Pair · Left' read 0 from 'Pair · Right' during Awake, but the real value is 42

Why: This is the shape of every script-execution-order bug: identical code, one succeeds, and which one succeeds can change between runs, between machines, and between a build and the editor. That is why the fix is never 'reorder the objects' - it is 'ask later'.

16. Why is a 0 worse than a crash?

Explain it to yourself

Discussion prompt

The too-early read returned 0 rather than throwing an exception. Explain why that is the more dangerous outcome.

Answer:

Because nothing tells you. An exception names the file and the line; a 0 is a plausible number that flows on into the rest of the game and shows up as 'the enemy has no health' three systems later.

It is also intermittent: the object that woke second worked perfectly, so half your test cases pass. The rule 'read in Start' is cheap insurance against a bug that hides.

17. Script Execution Order exists, and is a last resort

Concept

Edit > Project Settings > Script Execution Order lets you force some scripts to run their callbacks before others.

questionanswer
Does it work?yes, reliably
Should you reach for it?almost never
Why not?it is invisible from the code - the next reader has no clue it exists
When is it right?one global manager that genuinely must exist first, and even then Awake-then-Start usually solves it

Treat needing it as a signal that something is being read too early. Ninety-nine times in a hundred, moving the read from Awake to Start is the real fix.

18. Awake or Start?

Discrimination

Sort each line by which callback it belongs in.

Sort into buckets

Which callback?

Awake - about me
Cache my own Rigidbody; Create the list this script will fill; Set my own health to its maximum
Start - about someone else
Read the GameManager's difficulty setting; Register myself with the spawn manager
awake
It only touches this object: its own components, its own fields, its own collections. Nothing else in the scene has to exist yet, so doing it first means everyone else can rely on you being ready.
start
It touches another object. Do it in Start and every Awake in the scene has already finished, so whoever you are talking to has published whatever they publish.

19. Complete the pair of callbacks

Fill the middle

Fill in the callback names so this script is set up safely.

Fill in the blanks

Rigidbody body;
GameManager manager;

void Awake()
Start

void ___()
___

Why: The split follows the ownership of what is being touched, not the complexity of the code. GetComponent on yourself is safe in Awake because you exist by definition; GameManager.Instance is only guaranteed to be set once the GameManager's own Awake has run, which the Start barrier guarantees.

20. Break the rule deliberately

Counterexample

Discussion prompt

Find a case where reading another object in Awake is genuinely safe. Then say what makes it safe, and why it is still a bad habit.

Hint: What if the other object was created by you, on the same line?

Answer:

If you Instantiate an object and then read it, its Awake has already run - Instantiate does not return until it has. So Instantiate(prefab).GetComponent<Enemy>().health = 50; is safe in Awake.

Why it is still a habit worth avoiding: the safety comes from a fact about that one line, not from the callback. Move the code, add a line, and the guarantee quietly disappears. Start is safe for a reason that survives editing.

21. Enabled, inactive, destroyed

Section

Part 3

22. Three states, different callbacks

Concept

A component's state decides which callbacks it gets. This is the table that explains 'my script stopped working and I never touched it'.

stateAwakeOnEnableStartUpdateOnDisable
normalyesyesyesyesat the end
component checkbox offyesnononono
object inactive at loadnonononono
object deactivated lateralready ranalready ranalready ranstopsyes

The bold cell is the surprise: Awake runs on a disabled component. Awake is about the object being created, not about it running - which is why caching there is safe even for scripts that start switched off.

Unity Scripting API - MonoBehaviour.OnEnable OnEnable

23. Predict: the disabled component

Prediction

You untick the checkbox beside a script - the component's own checkbox, not the object's - and press Play.

Predict first

Which callbacks run?

  • None
  • Awake only
  • Awake and Start
  • All of them - the checkbox only hides it

Correct: Awake only.

Why: Awake runs because the component exists. OnEnable, Start and Update do not, because it is not enabled. Tick the box later at runtime and OnEnable runs, followed by Start - Unity holds Start until the first frame the component is actually enabled.

24. Deactivate mid-run and watch

Worked example

The lab's third cube switches itself off at t = 2s. Note what does NOT appear.

void Update()
{
    if (!disabledYet && Time.timeSinceLevelLoad >= 2f)
    {
        disabledYet = true;
        gameObject.SetActive(false);     // OnDisable runs; OnDestroy does not
    }
}
momentcallbackwhy
t = 0Awake, OnEnable, Startnormal startup
t = 0 to 2sUpdate every framerunning
t = 2sOnDisableswitched off - still in the scene
t = 2s onwardnothingan inactive object runs no callbacks
you press StopOnDisable, then OnDestroythe scene is torn down

The last row is worth remembering: OnDisable always runs before OnDestroy. Anything you unsubscribe in OnDisable is already unsubscribed by the time OnDestroy runs.

25. Order a full life

Ranking

An object is created, deactivated at t = 2s, reactivated at t = 4s, then Play stops. Order the callbacks.

Put in order

Earliest first.

  1. Awake
  2. OnEnable (startup)
  3. Start
  4. OnDisable (t = 2s)
  5. OnEnable again (t = 4s)
  6. OnDisable (Play stops)
  7. OnDestroy

Why: Start appears exactly once in that list even though the object was enabled twice - Start is once per component, ever. OnEnable and OnDisable pair up any number of times, which is precisely why event subscription belongs in that pair and not in Start.

26. Trap: subscribing in Start, unsubscribing in OnDestroy

Trap

The trap

Set up once, tear down once. It reads symmetrically, so it must be right.

void Start()      { GameEvents.OnScore += HandleScore; }
void OnDestroy()  { GameEvents.OnScore -= HandleScore; }
  • Deactivate the object: it is still subscribed, and HandleScore still runs
  • It runs on an object that is switched off, which is rarely what anyone wants
  • Reactivate it and nothing re-subscribes - Start does not run twice
  • So one deactivate-reactivate cycle leaves you subscribed exactly once, by luck

The fix

Subscribe in OnEnable, unsubscribe in OnDisable. They pair up every time, however many times the object is switched on and off.

void OnEnable()   { GameEvents.OnScore += HandleScore; }
void OnDisable()  { GameEvents.OnScore -= HandleScore; }
eventOnEnable/OnDisableStart/OnDestroy
object deactivatedunsubscribes correctlystays subscribed - bug
object reactivatedre-subscribes correctlynever re-subscribes
object destroyedOnDisable runs first, so still correctworks

27. Find the lifecycle bug

Error analysis

A camera follow script. It compiles and it looks fine.

Annotate

  • Reaching for another object during Awake. GameObject.Find only returns ACTIVE objects, and if the player is spawned by another script's Start or Awake, this returns null and the next line throws.
  • Second problem: GameObject.Find searches by name across the whole scene every call. Fine once in Start; a real cost if it ever creeps into Update.
  • Camera follow in Update means the camera reads the player's position BEFORE the player has necessarily moved this frame. LateUpdate is the fix, and the symptom of getting it wrong is camera jitter.

Two lifecycle bugs in twelve lines, and neither is a compile error. Both fixes are one word: Awake becomes Start, Update becomes LateUpdate.

28. Complete the callback matrix

Comparison

Fill the blanks from the rules you now have.

Comparison matrix

Runs on a disabled component?Runs more than once?Safe to touch other objects?
Awakeyesnono
OnEnablenoyesusually
Startnonoyes

29. Inside one frame

Section

Part 4

30. Three update callbacks, in order

Concept

Within a single frame Unity runs FixedUpdate (zero or more times), then Update, then LateUpdate. The order is fixed and it is the reason LateUpdate exists.

void FixedUpdate() { /* physics: forces, velocity, MovePosition   */ }
void Update()      { /* input, timers, game logic, non-physics    */ }
void LateUpdate()  { /* camera follow, anything needing finals    */ }
callbacktimes per frameclock
FixedUpdate0, 1, 2 or morephysics: 0.02s per step
Updateexactly 1frame: Time.deltaTime
LateUpdateexactly 1, after every Updateframe: Time.deltaTime

31. Predict: FixedUpdate zero times?

Prediction

The row above says FixedUpdate may run zero times in a frame.

Predict first

When would a frame contain no FixedUpdate at all?

  • Never - it always runs at least once
  • When the frame was so short that no 0.02s of simulated time has elapsed
  • When there are no Rigidbodies in the scene
  • Only when the game is paused

Correct: When the frame is shorter than the remaining physics step.

Why: At 144 fps a frame is about 0.007s, and the physics step is 0.02s - so roughly two frames in three contain no physics step. This is why 'once per frame' and 'once per step' are genuinely different rates in both directions, not just when the machine is struggling.

32. Why camera follow goes in LateUpdate

Worked example

The player moves in Update. The camera wants the position after that move.

// on the camera
void LateUpdate()
{
    transform.position = target.position + offset;
}
camera code inplayer moved this frame?camera shows
Update, camera runs firstnot yetlast frame's player position - one frame behind
Update, camera runs secondyescorrect, by luck of execution order
LateUpdateyes, guaranteedcorrect, always

The symptom of getting it wrong is subtle: the camera does not break, it lags, and the player reads that as jitter or motion sickness rather than as a bug.

33. Watch what holds across the frame

Invariant

Step through one frame at 144 fps and watch which counter changes.

Step through it

Which of these is constant across all three frames, and why does that matter?

  1. no step due
  2. one step
  3. no step due

Update and LateUpdate are exactly 1 per frame, always. FixedUpdate is whatever the clock says - so code that assumes 'one physics step per frame' is wrong in both directions.

34. Where should this code live?

Trade off

Weigh the two options for a piece of code that moves an object smoothly.

Comparison matrix

In UpdateIn FixedUpdate
Runs how oftenonce per frame50 times a second
Looks smoothyes - matches the displayonly with interpolation on
Collisions handlednoyes
Frame-rate independentonly with Time.deltaTimeyes, inherently

So: no Rigidbody, move in Update with Time.deltaTime. Rigidbody, move in FixedUpdate and set the body's Interpolate to Interpolate so the rendering smooths between steps.

35. Explain the two clocks in two sentences

Explain it

Discussion prompt

A teammate asks why their character 'stutters' when they move it in FixedUpdate. Answer in two sentences.

Answer:

Model answer: 'Physics updates 50 times a second but your screen draws 144, so the character's position only actually changes on some frames and the eye reads that as stutter.'

'Set the Rigidbody's Interpolate to Interpolate - it draws the body smoothly between physics steps without changing the simulation at all.'

36. Build it in Unity

Section

Build

37. What you are about to build

Concept

A scene that prints its own lifecycle: three logged objects, one that switches itself off, and the two-object pair that fails when it reads too early.

LifecycleLogger
Numbers every callback with a shared counter and a frame stamp.
WhyAwakeThenStart
The read-too-early bug, with a switch to fix it.

Files: unity-labs/Assets/NaruhodoLabs/Lesson04_Lifecycle/.

38. Plan the experiment

Step zero

Discussion prompt

What is the smallest scene that proves 'every Awake finishes before any Start'? What must be true of the logging for the proof to hold?

Answer:

  • Two objects minimum - one object cannot demonstrate ordering between objects
  • A shared counter, not a per-object one, or both objects print 1, 2, 3 and prove nothing
  • The object name on every line, or you cannot tell whose callback fired
  • A frame stamp, so 'same frame' versus 'next frame' is visible

That is the difference between a log and evidence.

39. Step 1: build and read the log

Worked example

Two cubes with the logger, then read the Console top to bottom.

// the line that does the work
Debug.Log($"{order,3}  {callback,-12} on '{name}'  frame {Time.frameCount}");
you should seegrouped how
Awake on A, Awake on Bboth before any OnEnable
OnEnable on A, OnEnable on Bboth before any Start
Start on A, Start on Bboth before any Update
FixedUpdate, then Update, then LateUpdatethe frame order, every frame

Which of A or B goes first inside a phase may differ on your machine. That is not a bug - it is exactly the thing you are not allowed to depend on.

40. Step 2: run the pair, then fix it

Worked example

Both pair objects start with Read In Awake ticked. One line will be a FAIL.

void Awake()
{
    Published = myNumber;
    if (readInAwake) Check(partner.Published == partner.myNumber);
}

void Start()
{
    if (!readInAwake) Check(partner.Published == partner.myNumber);
}
settingLeft readsRight readsresult
Read In Awake ticked07one FAIL, one lucky PASS
Read In Awake unticked427two PASS, every run

Untick the box on both and run again

Why: Nothing about the values changed. Only when the question was asked - which is the entire lesson in one experiment.

41. Commit before you run it

Hypothesis

You untick the object's checkbox on cube A (top of the Inspector) before pressing Play.

Predict first

How many of A's callbacks appear in the Console?

  • All of them
  • Awake only
  • None at all
  • Awake and OnDisable

Correct: None at all.

Why: An inactive GameObject is not started up, so not even Awake runs. That is different from a disabled component, where Awake does run - and the difference is exactly the distinction between the object's switch and the component's switch from lesson 1.

42. Where this shows up in a real game

Real world

Discussion prompt

Your game has a GameManager holding the score, a HUD that displays it, and 20 enemies that report kills to the manager. Where does each piece of setup go, and why?

Answer:

  • GameManager.Awake - set up its own score, its own singleton reference. Nothing else needed.
  • HUD.Start - find the GameManager and read the current score. By Start the manager has definitely woken.
  • Enemy.Start - register with the manager. Same reason.
  • HUD.OnEnable / OnDisable - subscribe and unsubscribe from the score-changed event, so a HUD hidden during a cutscene stops listening and starts again cleanly.
  • Enemy.OnDestroy - report the kill. It runs whether the enemy died in combat or the level was unloaded, which may or may not be what you want - a case where being deliberate matters.

Notice the shape: every 'me' goes in Awake, every 'them' goes in Start, and every 'while I am switched on' goes in the OnEnable/OnDisable pair.

43. Now break it, on purpose

Concept

Six experiments from the lab notes.

changewhat happens
Untick the component checkbox before PlayAwake runs; Start and Update do not
Untick the object checkbox before Playnothing runs at all, not even Awake
Re-enable an object that switched itself offOnEnable runs again; Start does not
Rename Start to startit silently stops being called - no error
Add a second logger to the same objectboth log; callbacks are per component
Set Time.timeScale = 0Update keeps running, FixedUpdate stops

44. One symptom, four suspects

Elimination

A script's Update never runs, and there are no errors in the Console.

Eliminate the wrong options

Which explanation should you check FIRST?

  • A. The object or the component is switched off - or a parent above it is.
  • B. Update is misspelled.
  • C. The script is not attached to anything in the scene.
  • D. Another script is calling Destroy on it during Awake.

Survives elimination: A

Why: Check the cheapest and commonest cause first: two checkboxes, plus every parent in the Hierarchy. An inactive parent is the sneaky one, because the object's own checkbox is still ticked and activeSelf is still true - which is exactly what activeInHierarchy exists to tell you.

45. Read a lifecycle log line by line

Notation

Four lines of real output. Every field is there for a reason.

Annotate

  • Numbers 1 and 7 with other objects' callbacks in between: the gap is the proof that Unity interleaved the phases across objects rather than finishing one object at a time.
  • Both Awake and Start are on frame 1. Startup is not spread over several frames - it all happens before the first one is drawn.
  • FixedUpdate appears BEFORE Update in the frame, which is why a force applied this step is already reflected by the time your Update logic looks at the body.
  • Frame 118 at roughly 60 fps is about two seconds in - the moment the object switched itself off. OnDisable, and no OnDestroy: it is off, not gone.

46. Once ever, or once each time?

Definition probe

Some callbacks fire once in a component's whole life. Others fire every time a switch is flipped. Sorting them correctly is most of what you need.

Sort into buckets

Once per component ever, or repeatable?

Once per component, ever
Awake; Start; OnDestroy
Every time it is switched on or off
OnEnable; OnDisable
once
Tied to the component existing or ceasing to exist. Re-enabling an object does not re-run these - which is exactly why setup that must repeat cannot live here.
many
Tied to the enabled state, which can flip any number of times. Anything that must be undone and redone - subscriptions, registrations, timers - belongs in this pair.

47. Fill in the skeleton

Faded example

A patrolling enemy. Put each line in the right callback.

Fill in the blanks

Rigidbody body;
WaypointRoute route;

void Awake()
GetComponent}<Rigidbody>();
}

void Start()
FixedUpdate

void ___()
___

Why: Three callbacks, three kinds of work: my own component in Awake, another object's data in Start, and a physics move on the physics clock. Notice that route is read in Start rather than Awake because RouteManager.Instance is another object's field - and it is only guaranteed to be set once that manager's own Awake has run.

48. What would you need to know?

Missing information

Discussion prompt

A teammate says 'my script isn't running'. Before looking at their code, what are the four things you need to know - and what does each answer rule out?

Answer:

  1. Is the GameObject active? Inactive means not even Awake runs - and check every parent, not just the object.
  2. Is the component enabled? Disabled means Awake ran but Start and Update did not, which produces 'it half works'.
  3. Is the script attached to an object in the OPEN scene? A script in Assets and nowhere else is inert.
  4. Does anything print at all? A Debug.Log in Awake separates 'never created' from 'created but not updating' in one run.

Those four questions land on four different rows of the state table, so whichever answer comes back non-obvious is the bug.

49. Predict the next line

Pattern

The log so far reads: Awake on A, Awake on B, OnEnable on A, OnEnable on B.

Predict first

What is the next line?

  • Update on A
  • Start on A
  • Awake on C - a third object
  • FixedUpdate on A

Correct: Start on A (or on B - within a phase the order is not guaranteed).

Why: The phases are Awake, then OnEnable, then Start, then the frame loop. Both OnEnables have fired, so the OnEnable phase is complete and Start is next. If a third object existed, its Awake would have appeared before any OnEnable - so the log rules that out too.

50. Two of these are true about Awake

Two truths and a lie

One is false. Rule it out and say what rules it out.

Eliminate the wrong options

Which claim about Awake is false?

  • A. Awake runs on a component whose checkbox is unticked.
  • B. Awake runs again when an object is deactivated and reactivated.
  • C. Awake runs during Instantiate, before Instantiate returns to the caller.

Survives elimination: B

Why: Awake is once per component, ever. Reactivating fires OnEnable, not Awake - and not Start either. That is the whole reason the OnEnable/OnDisable pair exists: it is the only pair that tracks the switch rather than the lifetime.

51. The procedure: choosing a callback

Pattern

Four questions. They answer 'where does this code go?' every time.

  1. Does it touch only this object? Yes - Awake.
  2. Does it touch another object? Yes - Start.
  3. Does it need to happen every time this object is switched on? OnEnable, with the matching teardown in OnDisable.
  4. Does it run continuously? Physics goes in FixedUpdate, everything else in Update, and anything that must see this frame's final positions in LateUpdate.

And one rule that catches the rest: if you are tempted to open Script Execution Order, you are reading something too early. Move the read to Start first.

52. Check 1: the order

Check

The question the diagnostic asked, and one step further.

Check your understanding

Two objects, A and B, each with a script defining Awake and Start. Which ordering is guaranteed by Unity?

  • A. A.Awake, A.Start, B.Awake, B.Start
  • B. Every Awake runs before any Start, but the order within each phase is not guaranteed (correct)
  • C. Start runs before Awake, because Start prepares the object for Awake
  • D. The Hierarchy order decides everything, top to bottom

Answer: B

Why: Unity runs the phases across all objects: every Awake, then every OnEnable, then every Start. Which object goes first inside a phase is not something to rely on, which is exactly why 'set up yourself in Awake, reach for others in Start' works.

Why A tempts people
That would be object-at-a-time, and it would remove the guarantee that makes Start useful - an object's Start could then run before another object's Awake.
Why C tempts people
Backwards. Awake is first, and its name says so - the object wakes up, then later it starts.
Why D tempts people
Hierarchy order sometimes correlates with what you see, but it is not a guarantee, and building on it produces bugs that appear only in a build.

53. Check 2: the disabled component

Check

This one separates 'knows the list' from 'knows the rules'.

Check your understanding

A component's checkbox is unticked in the Inspector before you press Play. Which callbacks run on it?

  • A. None
  • B. Awake only (correct)
  • C. Awake and OnEnable
  • D. Everything except Update

Answer: B

Why: Awake runs because the component exists - Awake is about creation, not about running. OnEnable, Start and Update all require the component to be enabled. Tick the box at runtime and OnEnable fires, then Start, then Update from that frame on.

Why A tempts people
That is what happens when the whole GameObject is inactive. A disabled component still wakes up, and that difference is the useful part of the rule.
Why C tempts people
OnEnable means 'was just enabled', which never happened here.
Why D tempts people
Start would also be skipped, and Start is the one whose absence usually causes the bug.

54. One question to sit with

Socratic

Discussion prompt

Unity could have had a single Setup callback instead of Awake and Start. What would break?

Answer:

Ordering between objects. With one callback, object A's setup either runs before or after object B's - and whichever way round it is, half of all cross-references are reading something that has not been set yet.

Two phases with a barrier gives every object a slot where it is guaranteed to be alone with itself, and a later slot where everyone is guaranteed to be ready. That is not a Unity quirk - it is the standard two-phase initialisation pattern, and it appears anywhere objects have to find each other.

55. Check 3: the event subscription

Check

The last one, and the most practical.

Check your understanding

Where should a script subscribe and unsubscribe from a global event?

  • A. Subscribe in Start, unsubscribe in OnDestroy
  • B. Subscribe in OnEnable, unsubscribe in OnDisable (correct)
  • C. Subscribe in Awake, unsubscribe in OnDestroy
  • D. Subscribe in Start, unsubscribe in Start

Answer: B

Why: OnEnable and OnDisable pair up every time the object is switched on and off, so the subscription always matches the object's running state. They also cover destruction, because OnDisable always runs before OnDestroy.

Why A tempts people
A deactivated object stays subscribed and keeps handling events while switched off - and it never re-subscribes when reactivated, because Start does not run twice.
Why C tempts people
Same problem as A, with an extra one: Awake also runs on disabled components, so a script that starts switched off would subscribe while inactive.
Why D tempts people
Unsubscribing in the same callback that subscribes means you were never subscribed. It is not a real option, but it is the shape of an actual bug when someone copies a line.

56. A number worth feeling

Estimation

A game runs for 10 minutes at 60 fps.

Predict first

Roughly how many times does one object's Update run?

  • 600
  • 3,600
  • 36,000
  • 360,000

Correct: About 36,000 times.

Why: 60 x 60 x 10 = 36,000. That is why a GetComponent call in Update is worth caring about and one in Start is not, and why the habit is 'find it once, keep the reference'. Multiply by 200 objects and you are at seven million calls for something you could have done once.

57. What this unlocks

Concept

Lesson 5 is the direct payoff: GetComponent in Awake, Instantiate in Start or Update, and Destroy with its end-of-frame delay all make sense only against this timeline.

you now havewhat it enables
the phase barriercross-object references that always work
OnEnable / OnDisablesubscriptions that survive being switched off
the frame ordercamera follow and physics in the right places
the state tablediagnosing 'my script does not run' in seconds

58. Connect it to something you know

Analogy

If you have written a constructor and an init method, or used a page-load event, this is the same shape.

Match the pairs

Match each Unity callback to its closest cousin.

  • u1. Awake
  • u2. Start
  • u3. OnEnable / OnDisable
  • u4. Update
  • o1. a constructor - set up your own fields
  • o2. an init step after everything is constructed
  • o3. adding and removing an event listener
  • o4. the main loop

Why: The Awake-as-constructor mapping is close enough to be useful and worth one caveat: an actual C# constructor on a MonoBehaviour runs at a time Unity does not define, on the wrong thread for most engine calls, which is why Awake exists at all rather than you using the constructor you already know.

59. Draw the timeline

Connect it up

Draw it

Draw a vertical timeline for two objects side by side. Mark Awake, OnEnable, Start, the frame loop, OnDisable and OnDestroy, and draw the barrier line that both objects must cross before either may run Start.

60. Before you close this

Exit ticket

Predict first

Which is still shakiest?

  • Why Awake and Start are separate
  • What runs on a disabled component vs an inactive object
  • OnEnable / OnDisable pairing
  • FixedUpdate vs Update vs LateUpdate

Correct: Whichever you picked - the lab scene prints the answer for all four in one Play session.

Why: This topic tested as Probably OK, so the goal here is not repair but depth: lesson 5 assumes the timeline, and a shaky spot now becomes a confusing null reference then. Run the lab and read the numbered log against the item you picked.

61. What you can now do

Recap

You can say where any piece of setup belongs, and why, without guessing.

Lab: unity-labs/Assets/NaruhodoLabs/Lesson04_Lifecycle/SETUP.md. Run the pair experiment both ways before moving to lesson 5.

Sources

  1. Unity Manual - Order of execution for event functions
  2. Unity Scripting API - MonoBehaviour.Awake
  3. Unity Scripting API - MonoBehaviour.Start
  4. Unity Scripting API - MonoBehaviour.OnEnable
  5. Naruhodo Unity Labs - Lesson 04 setup notes — unity-labs/Assets/NaruhodoLabs/Lesson04_Lifecycle/SETUP.md

Want this taught 1-on-1? Alexander tutors Unity Game Engine — $55/session, free consultation.

Book on Wyzant · Text (657) 465-8108