简体   繁体   中英

Can't stop a Coroutine in Unity

I'm trying to stop waves spawning upon player death but I cant seem to stop the coroutine. I don't really know how to attack this any more because adding if statements and breaks didn't work. How do I call StopCoroutine and have the routine stop? Would I need to introduce new methods and such?

void Start () {
    gameOver = false;
    StartCoroutine (SpawnWaves());
}

void Update()
{
    if (gameOver)
    {
        StopCoroutine(SpawnWaves());
    }
  }

IEnumerator SpawnWaves()
{
    yield return new WaitForSeconds(startWait);
    while (true)
    {
        for (int i = 0; i < hazardCount; i++)
        {
            GameObject enemy = enemies[Random.Range(0, enemies.Length)];
            Instantiate(enemy, spawnPosition1, spawnRotation1);
            Instantiate(enemy, spawnPosition2, spawnRotation2);
            Instantiate(enemy, spawnPosition3, spawnRotation3);
            Instantiate(enemy, spawnPosition4, spawnRotation4);
            Instantiate(enemy, spawnPosition5, spawnRotation5);
            Instantiate(enemy, spawnPosition6, spawnRotation6);
            yield return new WaitForSeconds(spawnWait);
        }
        yield return new WaitForSeconds(waveWait);
        enemies[0].GetComponent<EnemyBehviour>().currentHealth *= enemyHealthMultiplier;
    }
}
  1. You need to set gameOver to True when the player dies
  2. You also need to add logic to change while loop to false to get out of the while loop.

For example set gameOver = true when currentHealth == 0 inside the while loop and set while(gameOver == false)

I think the problem may be that when you call StopCoroutine() you aren't directing it to stop your specific instance of the coroutine. You instead need to store a reference to your coroutine and pass that as the parameter to your Stop.

IEnumerator wavecoroutine = SpawnWaves();
StartCoroutine(wavecoroutine);

...

StopCoroutine(wavecoroutine);

The full fix thanks to @AlexG's guidance

void Start () {
    gameOver = false;
    StartCoroutine (SpawnWaves());
}

IEnumerator SpawnWaves()
{
    yield return new WaitForSeconds(startWait);
    while (gameOver != true)
    {
        for (int i = 0; i < hazardCount; i++)
        {
            if(gameOver)break;
            GameObject enemy = enemies[Random.Range(0, enemies.Length)];
            Instantiate(enemy, spawnPosition1, spawnRotation1);
            Instantiate(enemy, spawnPosition2, spawnRotation2);
            Instantiate(enemy, spawnPosition3, spawnRotation3);
            Instantiate(enemy, spawnPosition4, spawnRotation4);
            Instantiate(enemy, spawnPosition5, spawnRotation5);
            Instantiate(enemy, spawnPosition6, spawnRotation6);
            yield return new WaitForSeconds(spawnWait);
        }
        yield return new WaitForSeconds(waveWait);
        enemies[0].GetComponent<EnemyBehviour>().currentHealth *= eenter code herenemyHealthMultiplier;
    }
}

ryeMoss actually has the correct answer. You don't need to change the conditions of your while loop, but instead need to make sure you're passing a reference value to the StopCoroutine method. You can see in the docs that that's exactly what they're doing.

The problem is when SpawnWaves is called it returns a new IEnumerator which is obviously not what you want when you're trying to stop it, haha.

Just change inside your Start method to

gameOver = false;
waves = SpawnWaves(); <-- or whatever you want to call it
StartCoroutine(waves); <-- using a reference

and then pass waves to StopCoroutine .

Always read the docs carefully; they're your best friend when learning new libraries, frameworks, etc. :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM