Time-Based Events in Unity: Why Coroutines Are the Wrong Tool for Delays, Repeats, and Cancellation
You need to delay an explosion by 2 seconds after a grenade lands. Simple enough. You write a coroutine. IEnumerator DelayedExplosion(), yield return new WaitForSeconds(2f), call the explosion logic. Maybe 10 lines if you're tidy. You feel good about it.
Then your designer says "the player should be able to defuse the bomb." Okay, now you need to store the Coroutine reference so you can call StopCoroutine(). But wait — what if the player defuses it before the coroutine starts? You need a null check. What if the game object gets destroyed mid-wait? Another null check. What if the player defuses it at the exact frame the coroutine completes? Race condition. Your 10 lines are now 25, and you haven't even handled the "show defused message vs. show explosion" branching yet.
This is the story of every time-based event in Unity. The first implementation is clean. The second requirement doubles the code. The third makes you question your career choices.
