Let's say I have two scripts:
- SpawnManager
- Enemy
In SpawnManager, I have the function SpawnEnemyWave that should instantiate 3 enemies, if the random number generator is lower than 5, then one of them should have a higher movement speed, the other shouldn't move at all.
In SpawnManager:
bool toughEnemy = true;
int waveNumber = 3;
float randomNumber = Random.Range(0, 10);
void Start()
{
    SpawnEnemyWave(waveNumber);
}
void SpawnEnemyWave(int enemiesToSpawn) 
{
    float randomNumber = Random.Range(0, 10);
    print(randomNumber);
    for (int i = 0; i < enemiesToSpawn; i++) 
    {
        if ((randomNumber < 5) && toughEnemy)
        {
            print("Tough");
            Instantiate(enemyPrefab, GenerateSpawnPosition(), enemyPrefab.transform.rotation);
            toughEnemy = false; //I make sure there is only one tough enemy per wave
        } 
        else
        {
            print("Weak");
            Instantiate(enemyPrefab, GenerateSpawnPosition(), enemyPrefab.transform.rotation);
        }
    }
}
In Enemy, I'm checking if the toughEnemy variable is set to true to modify the enemy speed before the instantiation, I put those if statements in the start function because I think than when an enemy is instantiated is when it is called.
void Start()
{
    spawnManager = GameObject.Find("Spawn Manager").GetComponent<SpawnManager>();
    if (spawnManager.toughEnemy)
    {
        speed = 1;
        print("Speed " + speed);
    }
    else
    {
        speed = 0;
        print("Speed " + speed);
    }
}
The problem is, when the random number is 0 in the logs i see this...
- random number:0
- Tough (the i in the for loop is 0)
- Weak (the i in the for loop is 1)
- Weak (the i in the for loop is 2)
- speed 0
- speed 0
- speed 0
And what I was expecting was something like below, because I'm modifying the variable in the SpawnManager script first before instantiating the enemy.
- random number:0
- Tough (the i in the for loop is 0)
- speed 1
- Weak (the i in the for loop is 1)
- speed 0
- Weak (the i in the for loop is 2)
- speed 0
What am I missing here?
 
                        
Timing. You’re partly correct thinking that
Startwill be called when the object is instantiated. But, it will be called when the next frame starts. In your current loop, you’re setting up the objects to be instantiated, then you set thetoughEnemyto true. When the next frame starts, all the enemies think that a tough enemy has been set, and the output you see is correct.If you want the manager to control the enemies, I’d personally include something like a
Setupmethod, called by the manager. For example, in theEnemyscript:Then, when you instantiate the enemy in your manager, do something like:
Here’s the life cycle of a ‘frame’
Notice that the
Updatemethod processing occurs about in the middle of the frame lifecycle. You’re Instantiating 3 objects in the same Update method. THEN … the frame ends, and at the beginning of the next frame, theStartevent for each of the new objects is triggered.