Coroutinen beenden
Teil des Abschnitts Physik und Gameplay der Unity-Journey von Coddy. Lektion 26 von 71.
StartCoroutine gibt ein Coroutine zurück, ein Handle für die Coroutine, die damit gestartet wurde. Speichere es in einem Feld, und StopCoroutine(handle) stoppt diese Coroutine an der Stelle, an der sie pausiert ist: Die Zeilen nach ihrem yield werden nie ausgeführt. StopAllCoroutines() stoppt alle Coroutinen, die das Skript gestartet hat. Mit der Leertaste wird dieser Alarm ein- und ausgeschaltet:
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);
}
}Das Feld wird nicht von selbst geleert, wenn die Coroutine stoppt. Deshalb setzt der Alarm es wieder auf null, und die nächste Betätigung der Leertaste weiß, dass nichts läuft. Zwei Möglichkeiten, die richtig aussehen, funktionieren nicht. StopCoroutine(Beep()) ruft Beep() erneut auf, wodurch eine neue, noch nicht gestartete Coroutine erstellt wird, und stoppt diese. Deshalb piept der Alarm weiter. Und enabled = false schaltet Update() des Skripts aus, aber seine Coroutinen laufen weiter. Eine Coroutine endet, wenn sie über ihr Handle oder durch StopAllCoroutines() gestoppt wird, wenn sie ihre letzte Zeile erreicht oder wenn ihr GameObject mit SetActive(false) deaktiviert oder zerstört wird.
Aufgabe
EinfachLass einen Klick die Bombe entschärfen, ohne das Skript auszuschalten.
- Füge ein Feld
Coroutine fuse;hinzu. Bei Leertaste setzefuse = StartCoroutine(Fuse());. - Ersetze bei einem Klick
enabled = false;: Wennfuse != null, rufeStopCoroutine(fuse);auf, setzefuse = null;und protokolliereDefused.
Drücke „Spielen“, drücke die Leertaste und klicke dann: Die Console zeigt Defused an und die Bombe bleibt bestehen. Drücke anschließend „Prüfen“.
Probier es selbst
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);
}
}
Alle Lektionen in Physik und Gameplay
1Rigidbody
Schwerkraft und MasseMit AddForce schiebenMit einem Impuls springenFixedUpdate für PhysikGeschwindigkeitKinematische KörperRückblick: Startrampe4Coroutinen
AufrufenWiederholt aufrufen, Aufruf abbrechenDeine erste CoroutineSchleifen in CoroutinenCoroutinen beendenRückblick: Countdown10Projekt: Arena-Flucht
Die ArenaJäger2Kollisionen
OnCollisionEnterWas habe ich getroffen?Beim Aufprall zerbrechenAuf dem Boden stehenAbprallen und ReibungCollider-FormenRückblick: Zerstörbare Wand5Projekt: Münzrausch
Der rollende BallMünzen zum Einsammeln11Abschließende Herausforderungen
KanonenreichweiteBewegliche ZieleMurmelgolfIns LochEscape RoomDie TürÜbe selbstständig: Unity-Playground