Menu
CoddyTech

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 icon

Challenge

Easy

Space 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);
    }
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Physics and Gameplay