Menu
CoddyTech

Zatrzymywanie korutyn

Część sekcji Fizyka i rozgrywka ścieżki Unity w Coddy. Lekcja 26 z 71.

StartCoroutine zwraca Coroutine, czyli uchwyt do uruchomionej przez nią korutyny. Zapisz go w polu, a StopCoroutine(handle) zatrzyma tę korutynę w miejscu, w którym została wstrzymana: wiersze po jej yield nigdy się nie wykonają. StopAllCoroutines() zatrzymuje każdą korutynę uruchomioną przez skrypt. Spacja włącza i wyłącza alarm:

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

Pole nie czyści się samo po zatrzymaniu korutyny, dlatego alarm ustawia je z powrotem na null, a po kolejnym naciśnięciu spacji wie, że nic nie działa. Dwa sposoby, które wydają się poprawne, nie działają. StopCoroutine(Beep()) ponownie wywołuje Beep(), co tworzy nową, jeszcze nieuruchomioną korutynę, i ją zatrzymuje, więc alarm nadal pika. Z kolei enabled = false wyłącza Update() skryptu, ale jego korutyny działają dalej. Korutyna kończy się, gdy zostanie zatrzymana za pomocą swojego uchwytu lub przez StopAllCoroutines(), gdy dotrze do ostatniego wiersza albo gdy jej GameObject zostanie dezaktywowany przez SetActive(false) lub zniszczony.

challenge icon

Wyzwanie

Łatwy

Spraw, aby kliknięcie rozbrajało bombę bez wyłączania skryptu.

  1. Dodaj pole Coroutine fuse;. Po naciśnięciu spacji ustaw fuse = StartCoroutine(Fuse());.
  2. Po kliknięciu zastąp enabled = false;: gdy fuse != null, wywołaj StopCoroutine(fuse);, ustaw fuse = null; i zaloguj Defused.

Naciśnij „Graj”, naciśnij spację, a potem kliknij: w konsoli pojawi się Defused, a bomba pozostanie na miejscu. Następnie naciśnij „Sprawdź”.

Spróbuj swoich sił

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

Wszystkie lekcje w sekcji Fizyka i rozgrywka

Poćwicz samodzielnie: Edytor online Unity