5
\$\begingroup\$

In my GameManager script, I instantiate a player game object, and call another method like this:

void Start()
{
   Debug.Log("GameManager Start() called...");
   Instantiate(player, Vector3.zero, Quaternion.identity);
   InitNewLevel();
}

void InitNewLevel()
{
    Debug.Log("GameManager InitNewLevel() called...");
}

In my Player script, I have this:

void Start()
{
    Debug.Log("Player Start() called...");
}

I was expecting Player.Start() to be called after the Instantiate(player, Vector3.zero, Quaternion.identity); line, and before the InitNewLevel(). However, if I look at my debug log output, I see this:

GameManager Start() called...
GameManager InitNewLevel() called...
Player Start() called...

Why do my methods execute in this order? Why does Player.Start() get called after GameManager.InitNewLevel?

\$\endgroup\$
9
\$\begingroup\$

The order is:

  1. Instantiate or AddComponent called by our spawning method
  2. Awake() <-- You can think of this like a "Constructor" for MonoBehaviours
  3. OnEnable(), skipped if script is disabled in prefab or GameObject is inactive
  4. Instantiate or AddComponent return and the calling method continues executing

As Gnemlock points out, Start will get called later after the calling method has completed (if the script & its gameObject are enabled/active), but before the newly-spawned script instance gets its first Update or FixedUpdate, ie...

  1. (Sometime later) Start()
  2. FixedUpdate(), skipped if there's no physics tick this frame (short frame), or called multiple times we tick multiple times this frame (long frame)
  3. Update()
  4. LateUpdate()

Here's a script you can use to test & verify this yourself:

public class InstantiatorTest : MonoBehaviour {

    static bool hasSpawned;

    // Editor-only, zeroth for objects already in the scene.
    void OnValidate()
    {
        Debug.Log(gameObject.name + " Validated");
    }

    // First!
    void Awake()
    {
        Debug.Log(gameObject.name + " Awake");
    }

    // Second!
    void OnEnable()
    {
        Debug.Log(gameObject.name + " Enabled");
    }

    // Third!
    void Start () {
        Debug.Log(gameObject.name + " Start");

        if (!hasSpawned)
        {
            hasSpawned = true;

            var go = new GameObject("spawned");
            go.AddComponent<InstantiatorTest>();

            Debug.Log("Spawn returned.");
        }
    }

    // Fourth! (If enough time has elapsed)
    void FixedUpdate()
    {
        Debug.Log(gameObject.name + " Fixed");
    }

    // Fifth!
    void Update () {
        Debug.Log(gameObject.name + " Update");
    }
}
\$\endgroup\$

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.