Advanced Coroutine Patterns
Real coroutines usually need more control than a single loop: waiting on conditions, nesting, and stopping cleanly.
IEnumerator SpawnWave(int count)
{
for (int i = 0; i < count; i++)
{
Instantiate(enemyPrefab, RandomSpawnPoint(), Quaternion.identity);
yield return new WaitForSeconds(1.5f);
}
}
IEnumerator WaitForPlayerReady()
{
yield return new WaitUntil(() => player.IsReady);
Debug.Log("Player ready, starting match");
}
Useful yield instructions
| Instruction | Waits for |
|---|---|
yield return null | next frame |
yield return new WaitForSeconds(t) | t seconds, scaled by Time.timeScale |
yield return new WaitForSecondsRealtime(t) | t real seconds, ignores pause |
yield return new WaitUntil(() => condition) | condition to become true |
yield return StartCoroutine(Other()) | a nested coroutine to finish |
Stopping coroutines
Coroutine handle = StartCoroutine(SpawnWave(5));
...
StopCoroutine(handle); // stop a specific one
StopAllCoroutines(); // stop everything running on this MonoBehaviour
A coroutine also stops automatically if the GameObject it's running on is destroyed or disabled.