Menu
CoddyTech

Stopping Coroutines

Part of the Physics and Gameplay section of Coddy's Unity journey. Lesson 26 of 71.

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

Make a click defuse the bomb without switching the script off.

  1. Add a field Coroutine fuse;. On Space, set fuse = StartCoroutine(Fuse());.
  2. On a click, replace enabled = false;: when fuse != null, call StopCoroutine(fuse);, set fuse = null; and log Defused.

Press Play, press Space, then click: the Console shows Defused and the bomb stays. 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);
    }
}

All lessons in Physics and Gameplay

Practice on your own: Unity playground