Stopping Coroutines
Part of the Physics and Gameplay section of Coddy's Unity journey. Lesson 25 of 63.
StartCoroutine returns a Coroutine, a handle to the coroutine it started. Keep it in a field, and StopCoroutine(handle) stops that coroutine where it is paused: the lines after its yield never run. StopAllCoroutines() stops every coroutine the script started. Space switches this alarm on and off:
Coroutine beeping;
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
if (beeping == null)
{
beeping = StartCoroutine(Beep());
}
else
{
StopCoroutine(beeping);
beeping = null;
}
}
}
IEnumerator Beep()
{
while (true)
{
Debug.Log("Beep");
yield return new WaitForSeconds(1f);
}
}The field does not empty itself when the coroutine stops, so the alarm sets it back to null, and the next Space knows nothing is running. Two ways that look right do not work. StopCoroutine(Beep()) calls Beep() again, which makes a new, unstarted coroutine, and stops that one, so the alarm keeps beeping. And enabled = false switches off the script's Update(), but its coroutines carry on. A coroutine ends when it is stopped through its handle or by StopAllCoroutines(), when it reaches its last line, or when its GameObject is deactivated with SetActive(false) or destroyed.
Challenge
EasySpace lights the Bomb's fuse: the Fuse coroutine logs Fuse lit, waits fuseTime (3) seconds, logs Boom and destroys the bomb. A click is meant to defuse it, but it switches the script off, and the bomb still goes off. Fix the defusing:
- A click while the fuse burns stops it and logs
Defused. The bomb stays. - Afterwards Space can light the fuse again, and that time, with no click, the bomb goes off 3 seconds later.
Press Play, light the fuse, click, and watch the Console, then Check.
Try it yourself
using System.Collections;
using UnityEngine;
public class Bomb : MonoBehaviour
{
public float fuseTime = 3f;
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
StartCoroutine(Fuse());
}
if (Input.GetMouseButtonDown(0))
{
enabled = false;
Debug.Log("Defused");
}
}
IEnumerator Fuse()
{
Debug.Log("Fuse lit");
yield return new WaitForSeconds(fuseTime);
Debug.Log("Boom");
Destroy(gameObject);
}
}
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Physics and Gameplay
1Rigidbody
Gravity and MassPush with AddForceJump with an ImpulseFixedUpdate for PhysicsVelocityKinematic BodiesRecap: Launch Pad4Coroutines
InvokeInvokeRepeating, CancelInvokeYour First CoroutineLoops in CoroutinesStopping CoroutinesRecap: Countdown2Collisions
OnCollisionEnterWhat Did I Hit?Break on ImpactStanding on the GroundBounce and FrictionCollider ShapesRecap: Breakable Wall