#question about spawning using coroutines

1 messages · Page 1 of 1 (latest)

plucky eagle
#

I have a question about coroutines. So I have a spawning system that I'm making for a tower defense game, and it has waves. So for a wave, I have the first enemy spawned immediately in a method, then I have a coroutine that spawns the rest of the enemies if there are any. I have a method for spawning the whole wave where it first calls SpawnFirstEnemy(), then i check if there is more than one enemy, and if there is I start the SpawnEnemy() coroutine. The problem is, if I have the spawn delay set to 2 seconds, the delay between the first and second enemies is 3 seconds instead of 2. It seems as though starting the coroutine takes a second, along with the little bit of calculations. from the second to third enemy and on, the spawn delay is 2 seconds, but not from 1 to 2. I'm just wondering why that is? I have a scuffed workaround, but I was hoping someone could explain. Anyway, here's my code for the class. ```java

public class WaveSpawner : MonoBehaviour {

[SerializeField] private Wave currentWave;

public bool isWaveFullySpawned;
private float spawnDelay;
private int numberOfEnemies;

private void Awake() {
    spawnDelay = currentWave.spawnDelay;
    numberOfEnemies = currentWave.enemiesInWave.Count;
}

private void Start() {
    SpawnWave(currentWave);
}


public void SpawnWave(Wave wave) {
    GameObject firstEnemy = wave.enemiesInWave[0];
    SpawnFirstEnemy(firstEnemy);

    if (numberOfEnemies > 1) {
        StartCoroutine(SpawnEnemy());
    }
    else {
        isWaveFullySpawned = true;
    }
}

public void SpawnFirstEnemy(GameObject firstEnemy) {
    Vector3 randomPosition = new Vector3(Random.Range(-9f, 9f), Random.Range(5f, -5f), 0f); //within the camera bounds
    ObjectPool.SpawnEnemy(firstEnemy, randomPosition, Quaternion.identity, ObjectPool.PoolType.Enemy);
    Debug.Log("Enemy spawned");
}

public IEnumerator SpawnEnemy() {

    for (int i = 1; i < numberOfEnemies; i++) {

        // find better way to deal with the one second delay after spawning the first enemy and calling this coroutine
        if (i == 1) {
            yield return new WaitForSeconds(spawnDelay - 1f); // if spawn delay is 2 seconds, technically this makes it 1, but the reason is that when the coroutine first starts, it takes one second so, just take that second away from the spawn delay for the second enemy spawned
        }
        else {
            yield return new WaitForSeconds(spawnDelay);
        }

        GameObject currentEnemy = currentWave.enemiesInWave[i];

        Vector3 randomPosition = new Vector3(Random.Range(-9f, 9f), Random.Range(5f, -5f), 0f); //within the camera bounds
        ObjectPool.SpawnEnemy(currentEnemy, randomPosition, Quaternion.identity, ObjectPool.PoolType.Enemy);
        Debug.Log("Enemy spawned");

        if (i == numberOfEnemies - 1) { // last element
            isWaveFullySpawned = true;
            Debug.Log("All enemies spawned");
            yield break;
        }
    }
}

}

#

first image is without the fix i have right now, the second is with

pastel basin
#

Why do you spawn the first enemy separately? Just call the corotuine to spawn enemies and it'll start from the first one. If there's only 1, the corotuine will just finish . . .

#

You don't need to check if i is the first or last enemy. Using yield break at the end of a coroutine is redundant. When the loop is complete, all enemies have spawned; just set isWaveFullySpawned after the loop. The coroutine stops running when the method ends . . .

plucky eagle
#

the reason I spawn the first enemy separately is so it instantly spawns and doesn't wait for the spawn delay. as for the other stuff, that's true, I just put it there to be explicit but I'll change it since it makes sense. Basically though, I just want my first enemy to be spawned and not have to wait for that delay.

pastel basin
#

Just call the spawn method before the delay and it'll spawn instantly . . .