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.
Aufgabe
EinfachSchreibe Ride, sodass das Fallgatter eine vollständige Fahrt macht.
- Setze
Vector3 up = down + Vector3.up * height;. Solangewhile (transform.position != up)gilt, bewege es mitVector3.MoveTowards(transform.position, up, speed * Time.deltaTime)undyield return null;. - Protokolliere
Open, dannyield return new WaitForSeconds(1f);. - Bewege es auf dieselbe Weise zurück nach
downund protokolliere dannClosed.
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
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