LateUpdate is called before Start? Bug

There seems to be a bug in Unity Engine that can cause LateUpdate to be called before Start in some cases. It does not seem to be an issue for Update.

The issue is in both 2021.3 and latest Unity 6. So I imagine it is also in all the version in between.
I’ve created a sample project to reproduce the issue.

Basically all the project does is Instantiate an object after 1 second, the object contains a parent script and a child scripts.

The result is the following:
execution

Which is Clearly wrong, not only the Start of child object is called after the parent LateUpdate, but also both Update function are called after LateUpdate, expected behavior should be
Start
Start
Update
Update
LateUpdate
LateUpdate

The scene has a basic manager that instantiate the object.

And the instantiated prefab has two scripts, TestParent.cs and TestChild.cs which are attached to the parent and child inside the prefab.

TestManager.cs

public class TestManager : MonoBehaviour
{
    public GameObject prefab;

    void Start()
    {
        StartCoroutine(StartDelayed());
    }

    private IEnumerator StartDelayed()
    {
        yield return new WaitForSeconds(1f);
        Instantiate(prefab, Vector3.zero, Quaternion.identity);
    }

}

TestParent.cs

public class TestParent : MonoBehaviour
{
    private bool first = false;
    private bool first_late = false;

    void Start()
    {
        Debug.Log("Start Parent");
    }

    void Update()
    {
        if (!first)
            Debug.Log("Update Parent");
        first = true;
    }

    void LateUpdate()
    {
        if (!first_late)
            Debug.Log("LateUpdate Parent");
        first_late = true;
    }
}

TestChild.cs is the same as TestParent.cs but it logs “child” instead of parent

The issue does not happen if you remove the coroutine and instead just Instantiate the object directly inside the Start function.

Sample Project:
TestTime.zip (32.6 KB)

Expected behaviour. Look at the timing graph: Unity - Manual: Order of execution for event functions

yield WaitForSeconds comes after Update. So your code going Start, LateUpdate, Update is expected.

It still doesnt really make sense why LateUpdate would be called before the other Start.

I thought all the Start functions are called before doing the Update. For example if you use Update instead of LateUpdate and instantiate an object with multiple components. All the Start will be called before the Update execute, but its not the case for LateUpdate.

IF i follow your execution order, then when is Start called exactly? How can it be in between WaitForSeconds and LateUpdate. I thought Start was called at the begining of the next frame.

RTFM: Unity - Scripting API: MonoBehaviour.Start()

Start is called on the frame when a script is enabled just before any of the Update methods are called the first time.

1 Like

Yes that’s what i thought, Start is supposed to be called BEFORE any of the update methods are called the first time.

But in my case its not, Start is called between WaitForSeconds and LateUpdate in my example, which is the confusing part. When it should be just before Update on next frame.

Uh, it is. LateUpdate counts to “any of the update methods”.

This includes all the hidden Update stages in the lower level player loop: UnityCsReference/Runtime/Export/PlayerLoop/PlayerLoop.bindings.cs at master · Unity-Technologies/UnityCsReference · GitHub

If you instantiate something at the very end of the player loop, Start is actually deferred to the next frame.

2 Likes

Yes i thought Start was always deffered to the next frame. THat’s how i thought it was working.

But apparently its not.

So in the case that i DONT define the LateUpdate function, would start be instead executed on next frame if the object is instantiate in a coroutine? Is it the fact that LateUpdate is defined that changes the timing?

It doesn’t care if you define it or not. It does what it says. If you instantiate something in PreUpdate, it gets initialised before Update. If you instantiate something in Update, it gets initialised before PreLateUpdate, and so on and so forth.

1 Like

Is there a way to make it wait a frame? So that the whole object is initialized before LateUpdate start running? And to make sure Update always run before LateUpdate

I guess i would need to add something like this to the start of ALL my LateUpdate?

if(!done_once)
{
    done_once = true;
     return;
}

Just spawn objects at the correct point in the player loop. I would imagine adding yeild return new WaitForEndOfFrame() would push a Start call onto the next frame.

That said, does it actually matter? Use Awake for self initialisation, and Start only when you need to initialise based on something else already having initialised itself. That’s all you need to worry about 99% of the time.

2 Likes

Yes i already do that.

In my case I was using Start because there was some initilization that need both the parent and child script to have self initialized with awake first. But I also want both Start to run before any of the LateUpdate run.

So basically
awake parent
awake child
start parent
start child
update parent
update child
lateupdate parent
lateupdate child

Then consider using OnEnable instead of Start.

As the docs mention, Start doesn’t get called until before the next update (any update) for each individual game object/component. So the behaviour you want from Start just isn’t how Unity works.

problem is that OnEnable would be called multiple times, since the objects get turned on/off based of distance to player.

i think its best to just skip first LateUpdate with a variable.

Then there should be no problem? The object gets spawned at the end of frame, Awake, then Start, then Update, then LateUpdate gets called.

In my actual project, its not inside a coroutine, thatsjust how i reproduced the issue in simpler project.
In my actual project the Instantiate is done inside another script Update when the conditions are met. Not sure how it could be delayed to end of frame inthat case

By “already do that” i mean self initialize in Awake… Not the waitforendframe

This is the kind of thing that makes me wish we had easy access to EarlyUpdate.

If you don’t feel like hooking into the player loop API yourself, you can always just spin up a coroutine to do the actual instantiating at the right point in time.

Alternatively, something like using async code with UniTask, which already hooks into the player loop for you, can let you await stuff until the correct point in the player loop quite easily: GitHub - Cysharp/UniTask: Provides an efficient allocation free async/await integration for Unity.

It’s still a bit confusing why LateUpdate would run before another Start function. I thought all the Start functions were supposed to run before any Updates. For example, if you use Update instead of LateUpdate and create an object with multiple components, all the Start functions should run before Update happens. But that’s not the case with LateUpdate.

So, with the execution order you mentioned, when exactly does Start get called? How can it happen between WaitForSeconds and LateUpdate? I thought Start was called at the beginning of the next frame.

1 Like

Unfortunately i think that would complexify the code way too much and lead to other issues if i start adding coroutine or try to delay tasks at the end of frame.

I just find it strange that not all the components on the same object get their start function called before any of the update/lateupdate are called.

Probably the best solution would be to remove the start/update/lateupdate function in the child object and instead have the parent call a custom function CustomStart CustomUpdate CustomLateUpdate in the other components so the execution order is always guaranteed.

Don’t make me RTFM you.