Остановка корутин
Часть раздела Физика и игровой процесс путешествия по Unity на Coddy. Урок 26 из 71.
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) либо уничтожают.
Задание
ЛегкоСделай так, чтобы щелчок обезвреживал бомбу, не выключая скрипт.
- Добавь поле
Coroutine fuse;. При нажатии Space установиfuse = StartCoroutine(Fuse());. - При щелчке замени
enabled = false;: еслиfuse != null, вызовиStopCoroutine(fuse);, установиfuse = null;и выведи в журналDefused.
Нажми «Играть», нажми Space, затем щёлкни: в Console появится Defused, и бомба останется на месте. Затем нажми «Проверить».
Попробуйте сами
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);
}
}
Все уроки раздела Физика и игровой процесс
1Твёрдое тело
Гравитация и массаТолкаем с помощью AddForceПрыжок с импульсомFixedUpdate для физикиСкоростьКинематические телаПовторение: пусковая площадка4Корутины
InvokeInvokeRepeating, CancelInvokeВаша первая корутинаЦиклы в корутинахОстановка корутинПовторение: обратный отсчёт10Проект: Побег с арены
АренаОхотники2Столкновения
OnCollisionEnterВо что я попал?Разрушение при столкновенииСтояние на землеОтскок и трениеФормы коллайдеровПовторение: разрушаемая стена5Проект: Монетная гонка
Катящийся шарСобираем монетыПотренируйтесь самостоятельно: Песочница Unity