Menu
CoddyTech

Schleifen in Coroutinen

Teil des Abschnitts Physik und Gameplay der Unity-Journey von Coddy. Lektion 25 von 71.

Eine Schleife mit einem yield return darin läuft über viele Frames, weil jeder Durchlauf vor dem nächsten pausiert. Mit WaitForSeconds wiederholt die Schleife etwas im Takt. Diese Sirene blinkt 3-mal:

IEnumerator Flash()
{
    for (int i = 0; i < 3; i++)
    {
        lamp.enabled = true;
        yield return new WaitForSeconds(0.2f);
        lamp.enabled = false;
        yield return new WaitForSeconds(0.2f);
    }
}

Mit yield return null macht die Schleife in jedem Frame ein kleines Stück weiter, bis ihre Bedingung erfüllt ist. So animiert eine Coroutine etwas. Dieser Ballon wächst bei einer Skalierung von 1 um 0.5 pro Sekunde, bis seine Skalierung 2 erreicht, und meldet dann:

IEnumerator Inflate()
{
    while (transform.localScale.x < 2f)
    {
        transform.localScale += Vector3.one * 0.5f * Time.deltaTime;
        yield return null;
    }
    Debug.Log("Full");
}

Time.deltaTime funktioniert hier wie in Update(): Die Coroutine wird einmal pro Frame fortgesetzt, und die Zeile nach der Schleife wird erst ausgeführt, wenn die Schleife beendet ist. Ohne yield läuft die gesamte Schleife innerhalb eines Frames, und der Ballon ist sofort voll. Eine while (true)-Schleife ist in einer Coroutine in Ordnung, solange sie bei jedem Durchlauf etwas zurückgibt. Ohne ein yield gibt sie den Frame nie zurück, und der Unity-Editor friert ein.

challenge icon

Aufgabe

Einfach

Schreibe Ride, sodass das Fallgatter eine vollständige Fahrt macht.

  1. Setze Vector3 up = down + Vector3.up * height;. Solange while (transform.position != up) gilt, bewege es mit Vector3.MoveTowards(transform.position, up, speed * Time.deltaTime) und yield return null;.
  2. Protokolliere Open, dann yield return new WaitForSeconds(1f);.
  3. Bewege es auf dieselbe Weise zurück nach down und protokolliere dann Closed.

Drücke „Spielen“ und dann die Leertaste: Das Tor hebt sich, wartet und schließt sich. Drücke anschließend „Prüfen“.

Probier es selbst

using System.Collections;
using UnityEngine;

public class Portcullis : MonoBehaviour
{
    public float speed = 1.5f;
    public float height = 3f;
    Vector3 down;

    void Start()
    {
        down = transform.position;
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            StartCoroutine(Ride());
        }
    }

    IEnumerator Ride()
    {
        // Fahre um height Einheiten mit speed nach oben und gib Open im Log aus, bleibe 1 Sekunde oben, fahre wieder nach unten und gib Closed im Log aus
        yield return null;
    }
}

Alle Lektionen in Physik und Gameplay

Übe selbstständig: Unity-Playground