Which came first; Awake(), OnEnable(), or Start()?

All Unity developers know that Awake() happens before OnEnable(), and both get called before Start(). Just to make sure, we visit the documentation to help us sleep at night. We never bothered to test it and simply assumed that all Awake() gets called before all OnEnable() before all Start(). But let’s say, out of boredom, we did test it.

Imagine 2 scripts, ScriptA and ScriptB, that do exactly the same thing: print out their game object’s name, script name, and the function being called (Awake(), OnEnable(), or Start()). Let’s have 2 game objects; Obj1, having both scripts, and Obj2, with just ScriptB. We run in the editor and see the logs to confirm what we already know.

Awake(), OnEnable(), and Start()

Surprise! Awake() can get called after OnEnable(). This may not look like a big deal until you start debugging with the wrong assumptions.

Let’s have another example; a single game object with a Rigidbody and the following 2 behaviors.

With the assumption that all Awake() gets called before all OnEnable(), then there should be no error. However, on the slight misfortune that ScriptD gets executed before ScriptC, ScriptD::OnEnable() will call ScriptC::Jump() before ScriptC gets to keep a reference to its Rigidbody, via ScriptC::Awake(). This results to a confusing Null Reference Exception that could haunt you for hours.

What the documentation doesn’t say is that Awake() is called before OnEnable() per behavior. All Start() occur after all Awake()/OnEnable(). We cannot determine which script gets executed first unless you manually specify that in the Script Execution Order Settings.

With that in mind, I pray to the Unity Gods that your bugs be all gone and your games be fun.

For those of you who are too lazy to type, feel free to download the source codes below.

ExecutionOrderTest
ExecutionOrderTest
ExecutionOrderTest.unitypackage
3.2 KiB
83 Downloads
Details

P.S. yes, you can color your Debug Log messages 😀