Hi Nina, I did as you suggested and I think I have an idea of what happened.
First, I littered (lol) my code with lots of Debug messages:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemySpawner : MonoBehaviour
{
/*[SerializeField]*/ List<WaveConfig> waveConfigs;
int startingWave = 0;
// Start is called before the first frame update
void Start()
{
Debug.Log("Begin of Start() at " + Time.frameCount);
waveConfigs = new List<WaveConfig> (Resources.FindObjectsOfTypeAll<WaveConfig>());
Debug.Log("Created list of waveConfigs in Start() at " + Time.frameCount);
var currentWave = waveConfigs[startingWave];
Debug.Log("Before calling coroutine in Start() at " + Time.frameCount);
StartCoroutine(SpawnAllEnemiesInWave(currentWave));
Debug.Log("After calling coroutine in Start() at " + Time.frameCount);
}
private IEnumerator SpawnAllEnemiesInWave(WaveConfig waveConfig)
{
Debug.Log("Begin of coroutine at " + Time.frameCount);
Debug.Log("Before loop in coroutine at " + Time.frameCount);
for (int enemyCount = 0; enemyCount < waveConfig.GetNumberOfEnemies(); enemyCount++)
{
var newEnemy = Instantiate(waveConfig.GetEnemyPrefab(), waveConfig.GetWayPoints()[0].position, Quaternion.identity);
var anotherEnemyInstantiation = Instantiate(waveConfig.GetEnemyPrefab(), waveConfig.GetWayPoints()[0].position, Quaternion.identity);
Debug.Log("Created new newEnemy object in coroutine at " + Time.frameCount);
newEnemy.GetComponent<EnemyPathing>().SetWaveConfig(waveConfig);
Debug.Log("Called setwaveconfig for newEnemy object in coroutine at " + Time.frameCount);
Debug.Log("Before yelding in coroutine at " + Time.frameCount);
Destroy(anotherEnemyInstantiation);
yield return new WaitForSeconds(waveConfig.GetTimeBetweenSpawns());
Debug.Log("After yelding in coroutine at " + Time.frameCount);
}
Debug.Log("After loop in coroutine at " + Time.frameCount);
}
}
And what I saw in execution order was what I expected in terms of the coroutine yelding execution back to the Start() method. BUT this didnāt explained my original question, of why SetWaveConfig() worked to change the enemy path after the enemy was instantiated.
What I did then: I created a second object INSIDE the coroutine, called SetWaveConfig() for it and immediately destroyed it before yelding, and the object was NOT drawn on the screen:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemySpawner : MonoBehaviour
{
/*[SerializeField]*/ List<WaveConfig> waveConfigs;
int startingWave = 0;
// Start is called before the first frame update
void Start()
{
Debug.Log("Begin of Start() at " + Time.frameCount);
waveConfigs = new List<WaveConfig> (Resources.FindObjectsOfTypeAll<WaveConfig>());
Debug.Log("Created list of waveConfigs in Start() at " + Time.frameCount);
var currentWave = waveConfigs[startingWave];
Debug.Log("Before calling coroutine in Start() at " + Time.frameCount);
StartCoroutine(SpawnAllEnemiesInWave(currentWave));
Debug.Log("After calling coroutine in Start() at " + Time.frameCount);
}
private IEnumerator SpawnAllEnemiesInWave(WaveConfig waveConfig)
{
Debug.Log("Begin of coroutine at " + Time.frameCount);
Debug.Log("Before loop in coroutine at " + Time.frameCount);
for (int enemyCount = 0; enemyCount < waveConfig.GetNumberOfEnemies(); enemyCount++)
{
var newEnemy = Instantiate(waveConfig.GetEnemyPrefab(), waveConfig.GetWayPoints()[0].position, Quaternion.identity);
Debug.Log("Created new newEnemy object in coroutine at " + Time.frameCount);
newEnemy.GetComponent<EnemyPathing>().SetWaveConfig(waveConfig);
Debug.Log("Called setwaveconfig for newEnemy object in coroutine at " + Time.frameCount);
// Creating another wave of enemies....
var anotherEnemyInstantiation = Instantiate(waveConfig.GetEnemyPrefab(), waveConfig.GetWayPoints()[1].position, Quaternion.identity);
anotherEnemyInstantiation.GetComponent<EnemyPathing>().SetWaveConfig(waveConfigs[1]);
// And destrying them BEFORE yelding, they're not draw on screen.
// Meaning, the drawing only occurs after returning to who called
// the coroutine, regardless of the instantiation inside the coroutine.
// IS THIS RIGHT?
Destroy(anotherEnemyInstantiation);
Debug.Log("Before yelding in coroutine at " + Time.frameCount);
yield return new WaitForSeconds(waveConfig.GetTimeBetweenSpawns());
Debug.Log("After yelding in coroutine at " + Time.frameCount);
}
Debug.Log("After loop in coroutine at " + Time.frameCount);
}
}
Conclusion : Regardless of the instantiation and setting of properties, components, etc inside the coroutine, the real āplacementā of an object on the game only happens after returning to the method who called it, in this case, Start(). I can do whatever I want with the newly created object inside the coroutine, but it is only inserted in the game after the coroutine yelding.
IS THIS RIGHT? Please confirm
Thank you!