Menu
CoddyTech

Остановка корутин

Часть раздела Физика и игровой процесс путешествия по Unity на Coddy. Урок 25 из 63.

StartCoroutine возвращает Coroutine — дескриптор запущенной им сопрограммы. Сохрани его в поле, и StopCoroutine(handle) остановит эту сопрограмму в месте приостановки: строки после её yield никогда не выполнятся. StopAllCoroutines() останавливает все сопрограммы, запущенные скриптом. Нажатие пробела включает и выключает этот сигнал:

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);
    }
}

Поле не очищается само, когда сопрограмма останавливается, поэтому сигнализация снова присваивает ему значение null, и при следующем нажатии пробела известно, что ничего не выполняется. Два способа, которые кажутся правильными, не работают. StopCoroutine(Beep()) снова вызывает Beep(), создавая новую, ещё не запущенную сопрограмму, и останавливает её, поэтому сигнал продолжает звучать. А enabled = false выключает Update() скрипта, но его сопрограммы продолжают выполняться. Сопрограмма завершается, когда её останавливают с помощью её дескриптора или StopAllCoroutines(), когда она доходит до последней строки либо когда её GameObject деактивируют с помощью SetActive(false) или уничтожают.

challenge icon

Задание

Легко

Пробел зажигает фитиль Bomb: корутина Fuse выводит в журнал Fuse lit, ждёт fuseTime (3) секунды, выводит Boom и уничтожает бомбу. Щелчок должен обезвредить её, но он выключает скрипт, и бомба всё равно взрывается. Исправь обезвреживание:

  • Щелчок, пока горит фитиль, останавливает его и выводит в журнал Defused. Бомба остаётся.
  • После этого пробел снова может зажечь фитиль, и на этот раз, если не щёлкать, бомба взорвётся через 3 секунды.

Нажми Играть, зажги фитиль, щёлкни и посмотри на Console, затем нажми Проверить.

Попробуйте сами

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 iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Физика и игровой процесс