Ryan W
Ryan W

Reputation: 41

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;
    }
}

Upvotes: 1

Views: 5304

Answers (5)

WJ C
WJ C

Reputation: 1

This is the latest correct answer:

Coroutine CO_WriteBleDevice = null;
IEnumerator DO_WriteBleDevice()
{
    // something work
    CO_WriteBleDevice = null;
}

void StartWriteBleDevice()
{
    if (CO_WriteBleDevice == null)
        CO_WriteBleDevice = StartCoroutine(DO_WriteBleDevice());
}

void StopWriteBleDevice()
{
    if (CO_WriteBleDevice != null)
    {
        StopCoroutine(CO_WriteBleDevice);
        CO_WriteBleDevice = null;
    }
}

Upvotes: 0

badross92
badross92

Reputation: 93

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. :)

Upvotes: 2

Ryan W
Ryan W

Reputation: 41

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;
    }
}

Upvotes: 2

ryeMoss
ryeMoss

Reputation: 4343

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);

Upvotes: 4

AlexG
AlexG

Reputation: 108

  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)

Upvotes: 4

Related Questions