0
\$\begingroup\$

I wonder how Unity's execution order really works. There's an ordered list at https://docs.unity3d.com/Manual/ExecutionOrder.html, but how does this work when there are different gameobjects involved? Will Unity first run the specific function for all the monobehaviours in the scene before it proceeds to the next function? Or will each monobehaviour go through that specific order of functions before Unity goes to the next monobehaviour? Or is it more complex? It isn't really clear to me from the documentation.

enter image description here

For example, normally Start() gets called before Update(), however when I was debugging, Update() on my Avatar prefab got called before Start() of my Camera child object. Is this supposed to happen?

\$\endgroup\$
2
  • 1
    \$\begingroup\$ This seems like something you can test for yourself. Put a Debug.LogFormat("Component {0} on object {1} had its [Event] method called", this.GetType(), name); in each method you want to check, replacing [Event] with the name of that event message. Then look at the order these print in your log. \$\endgroup\$ – DMGregory Sep 3 '20 at 15:04
  • \$\begingroup\$ @DMGregory It seems to be quite random. Sometimes it will execute all functions for a single script before it moves to the next script; sometimes it will execute start() on all scripts before it moves to update() on all scripts \$\endgroup\$ – xcrypt Sep 3 '20 at 15:18
2
\$\begingroup\$

As I mentioned in the comments, a simple way to investigate execution order in Unity is to add a debug log to each method you're interested in, something like...

Debug.LogFormat("{0}: [Event] called on {1}'s {2} at {3}",
                 Time.frameCount,
                 name,
                 this.GetType().Name,
                 Time.time);

Then you can read the sequence of messages and frame time stamps in the log to find out exactly what order each method was called in.

You'll find that this varies between objects that already existed, enabled in your scene from the beginning of the frame, and new objects that get created or enabled midway through the frame.

For script instances already present in your scene, at load:

  1. Each script instance gets its Awake method called, then its OnEnable method, if enabled, back-to-back. Then then the next script instance gets its Awake called, so you'll see an alternating pattern of Awake OnOnable Awake OnEnable if you log it as I recommended.

    This is why these two methods are shown bundled together as "Initialization" in the Unity execution order diagram.

  2. Then all the Start methods are called, on all script instances.

  3. Then all the FixedUpdate methods for the first physics step.

  4. Then all the Update methods for the variable time step.

  5. Then all the LateUpdate methods.

For subsequent frames, this process repeats for all enabled objects remaining from previous frames, starting from step 3 if there's one or more physics steps to evaluate this frame, and otherwise skipping ahead to step 4.

In my tests, the order in which particular script instances get their message method called within any given step appears to be the reverse order of creation, with the components I added last getting their method called first. I wouldn't count on this level of micro-ordering for your scripts though, as it's something the engine could be expected to change when optimizing a build.

This means the order can hop back-and-forth between GameObjects in the hierarchy, and does not necessarily process all scriot instances on a single object consecutively, before scripts on its child objects, etc. (This is to be expected, since we can override the order of executing particular script classes independent of how they're arranged on objects in the scene).

If a new script instance is spawned mid-frame, with Instantiate or AddComponent:

  1. Its Awake and OnEnable (if enabled) methods get called back-to-back.

  2. The Instantiate or AddComponent call returns, and control flow resumes on the next statement of the method that spawned the script, and the engine continues processing whatever message it was processing at the time.

  3. The engine moves on to the next update step (FixedUpdate, Update, LateUpdate, etc.)

    That means the new script instance has "missed the bus" for the current processing step, but can still catch the next one after this. If it was spawned during Update, it doesn't get an Update call this frame. But it could still get a LateUpdate.

  4. When the new script instance's turn comes in the next processing step (ie. FixedUpdate/Update/LateUpdate), Unity checks to see if it's been started yet. If not, it calls Start on this instance "just in time," then proceeds with processing its message method call.

  5. Just before rendering, if any newly-spawned scripts still haven't started (eg. they were spawned in LateUpdate), Unity calls Start on those stragglers.

So, these newly-created or newly-enabled objects could be the reason you're observing Start or other messages sometimes getting called in the middle of some other phase of processing. It's the engine playing catch-up to get the newly-added or -awoken instance up to speed for wherever the rest of the scene objects have advanced to in the update order.

\$\endgroup\$
3
  • \$\begingroup\$ I tested your suggestion earlier. It seems like you can always count on Awake() being called before Start() on different gameobjects, but not on Start() being called before Update() on different scripts. Unity will often do Update() right after Start() for one single script before it moves to the Start() of the next script, however this isn't always the case. \$\endgroup\$ – xcrypt Sep 3 '20 at 15:46
  • \$\begingroup\$ @xcrypt That doesn't sound right. Keep in mind that if you add an object to the scene after the scene starts (e.g. with Instantiate(prefab)), its Start() function will get called when it is added to the scene. \$\endgroup\$ – Kevin Sep 3 '20 at 19:48
  • \$\begingroup\$ @Kevin test it, you'll see. \$\endgroup\$ – xcrypt Sep 5 '20 at 13:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.