yield return new waitforseconds(5f) doesn't finish

I have written the following piece of code and the problem is that the WaitForSeconds Method doesn’t exit / finishes and I don’t know why.

IEnumerator increaseDelay(){
	ground.disable();
	float oldDelay = spawn.getDelay ();
	spawn.setDelay (spawnRate);
	yield return new WaitForSeconds (5f);
	spawn.setDelay (oldDelay);
	ground.enable ();
}

The only reasons why a coroutine won’t finish executing is:

  • You destroyed the gameobject or the MonoBehaviour which the coroutine runs on. The hosting MonoBehaviour is the one where you used StartCoroutine, not necessarily where the coroutine is located.
  • You deactivated the gameobject or disabled the hosting MonoBehaviour.
  • You called StopAllCoroutines or StopCoroutine manually which stops the execution.

Keep in mind that coroutines can only be stopped / aborted at “yield points” as those are the points where the control is passed back (yielded) to Unity. At this time you most likely performed any of the above mentioned steps which will terminate the coroutine at the current point.

Coroutines are not “methods” but are translated into statemachine objects. Each call of “MoveNext” on the IEnumerator object will advance the statemachine to the next yield. Unity will do that internally. It inspects the “Current” value of the statemachine and based on that value it decides when to resume this coroutine.

When the MonoBehaviour is destroyed the coroutines stored internally will simply be removed along.

Following can be reasons due to which your coroutine gets stuck on WaitForSeconds:

  1. The time given in WaitForSeconds is too long. Although this is silly reason, but sometimes this happens

  2. The object from which you are calling the coroutine is getting destroyed. You can check that as follow.

    void OnDestroy() {
        Debug.Log("Destroyed");
    }
    
  3. From any place, StopAllCoroutines() is getting called which is stopping your coroutine.

  4. Lastly, check that anywhere Time.timeScale is getting set to 0. Because when its zero, it stops Time.deltaTime from increasing and as a result WaitForSeconds never reaches your specified value.You can check your current timescale in Edit -> Project settings -> Time check Time Scale parameter in that. Or you check its value by logging before your coroutine is called.

Had to use “WaitForSecondsRealtime()” since i am altering the Time.timeScale = 0…
If anyone has the same iossue trey this

add

yield return null;

at the end of the coroutine.

I have run into this issue before, and it happens when I call my coroutine directly like a method.

It’s an easy mistake to overlook.

The proper way to call a coroutine is: StartCoroutine(myFunction());