Search code examples
c#unity-game-enginedelayspawn

Changing delay spawn at runtime [C#]


this is the code where the problem is situated:

public class EnemySpawnScript : MonoBehaviour {
    private float previousEnemyDelay = 0;

    public void enemySpawn (GameObject player, LevelData level){
        //loop every enemy inside the level to instantiate them. EnemyDataSpawn has got some infos about every enemy
        foreach (EnemyDataSpawn enemyDataSpawn in level.enemyDataSpawner) {
            StartCoroutine (InstantiateObject (player,enemyDataSpawn));
        }
    }

    IEnumerator InstantiateObject (GameObject player, EnemyDataSpawn enemyDataSpawn)
    {
        //this handles the delay of the spawn of every enemy. 
        previousEnemyDelay += enemyDataSpawn.delay;
        //here is the problem if i want to stop enemies to spawn and then continue to spawn them again.
        yield return new WaitForSeconds (previousEnemyDelay);
        //after waiting, i do something.
}

This code works if I just want to instantiate every enemy after a delay specified inside enemyDataSpawn (I didn't write the "instantiate enemy" part (i used object pooling to achieve that), situated after the yield inside IEnumerator because it's not important for my problem). The problem is that i have an integer (called maxOnScreen) for every kind of enemy, and if the number of the ACTIVE enemies with the same name is equal to maxOnScreen, then i want to stop to instantiate every other enemy until one enemy (which active number was equal to maxOnScreen) will be deactivated or destroyed. If one enemy is not activated anymore and the number of active enemies with the same name is not equal to maxOnScreen anymore, than I want to instantiate the next enemy in the list again with his delay as my actual code already does. I don't know how to achieve this with IEnumerator so my question is: is it possible to achieve this with IEnumerator or i should use some other methods?

Simple example: there are 7 enemies active, 3 named "bad soldier" and 4 named "good soldier". The maxOnScreen variable of good soldier is "4" so i don't want that other enemies will instantiate unless one of "good soldier" will be destroyed/deactivated. If the total of active "good soldier" is 3 (so less than maxOnScreen again), i want that the game goes on spawning the remaining enemies to spawn.

Thank you in advance


Solution

  • You might use a single enemy-spawning coroutine instead of launching each coroutine for each enemy you want to spawn. This way you can easily control when to spawn an enemy and when to delay its spawning:

    public class EnemySpawnScript : MonoBehaviour {
    
    public void enemySpawn (GameObject player, LevelData level){
        StartCoroutine(InstantiateObjects(player, level.enemyDataSpawner));
        }
    
        IEnumerator InstantiateObjects (GameObject player, IEnumerable<EnemyDataSpawn> enemyDataSpawnList){
    
            foreach(var enemyDataSpawn in enemyDataSpawnList){
    
                while( /* too many enemies of enemyDataSpawn type */ ) {
                    yield return new WaitForSeconds(enemyDataSpawn.delay);
                }
                // instantiate enemyDataSpawn
            }
    
        }
    }