Understanding Delays in Unity

If you’re gonna do stuff procedurally, this sorta thing can happen. Fortunately as other folks have pointed out above, there are some things you can do to mitigate against it.

However, the broad pattern I like to use when going procedural is the factory pattern. Any given component will have a static function used to Create it (or add it to an existing GameObject), in order to ensure it has what it needs without question.

Here is a trivial example of the pattern I use EVERYWHERE in my games to ensure order of initialization:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MyScript : MonoBehaviour
{
    // Always call this to create MyScript objects so we know they are complete.
    public    static    MyScript    Create(
        string resourcesPath,
        string additionalArgument1,
        int otherArgument)
    {
        // NOTE: only have ONE of the following two blocks of code, not both:

        // Option 1:
        // code for if this is a pre-defined prefab that you're going
        // to load, instantiate, and then customize a bit
        GameObject go = Resources.Load<GameObject>( resourcesPath);
        go = Instantiate<GameObject>( go);
        MyScript myScript = go.GetComponent<MyScript>();

        // Option 2:
        // code for making a new GameObject from scratch
        //MyScript myScript = new GameObject( "MyScript.Create();").
        //    AddComponent<MyScript>();

        // jam in the arguments we need
        myScript.additionalArgument1 = additionalArgument1;
        myScript.otherArgument = otherArgument;

        return myScript;
    }

    string additionalArgument1;
    int otherArgument;

    void Start()
    {
        /// etc...
    }

    void Update()
    {
        /// etc...
    }
}

This means outside of such a function you would NEVER use .AddComponent<>. And the above sample factory can be changed to accept an existing GameObject that it “installs” itself into, and correctly ensuring it has everything it needs to open up for business.

In the above case you would then call:

MyScript.Create( "Prefabs/MyPrefabForMyScript", "Arg1", 1234);

It returns the MyScript instance it created, so if you want, keep a reference to that. Meanwhile you can be confident that MyScript has everything it needs.