Thursday, December 3, 2015

c# - What is the order of execution, when calling an instantiation method, in Unity?


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?



Answer



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();

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");
}
}

No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...