Menu
CoddyTech

Loops in Coroutines

Part of the Physics and Gameplay section of Coddy's Unity journey. Lesson 25 of 71.

A loop with a yield return inside runs over many frames, because every pass pauses before the next. With WaitForSeconds the loop repeats something on a beat. This siren flashes 3 times:

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

With yield return null the loop does a little every frame until its condition is met, which is how a coroutine animates something. This balloon, at a scale of 1, grows by 0.5 a second until its scale reaches 2, then reports:

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

Time.deltaTime works here as in Update(): the coroutine resumes once per frame, and the line after the loop runs only when the loop is done. Without the yield, the whole loop runs inside one frame and the balloon is full at once. A while (true) loop is fine in a coroutine as long as it yields on every pass; without a yield it never gives the frame back, and the Unity editor freezes.

challenge icon

Challenge

Easy

Write Ride so the portcullis makes one full trip.

  1. Set Vector3 up = down + Vector3.up * height;. while (transform.position != up), move with Vector3.MoveTowards(transform.position, up, speed * Time.deltaTime) and yield return null;.
  2. Log Open, then yield return new WaitForSeconds(1f);.
  3. Loop back down to down the same way, then log Closed.

Press Play and press Space: the gate rises, waits and closes. Then Check.

Try it yourself

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()
    {
        // Rise height units at speed and log Open, stay 1 second, go back down and log Closed
        yield return null;
    }
}

All lessons in Physics and Gameplay

Practice on your own: Unity playground