Menu
CoddyTech

Циклы в корутинах

Часть раздела Физика и игровой процесс путешествия по Unity на Coddy. Урок 25 из 71.

Цикл с yield return внутри выполняется на протяжении многих кадров, потому что каждая итерация приостанавливается перед следующей. С помощью WaitForSeconds цикл повторяет действие в заданном ритме. Эта сирена мигает 3 раза:

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

С помощью yield return null цикл выполняет понемногу каждый кадр, пока не будет выполнено условие. Так корутина анимирует объект. Этот воздушный шар, изначально имеющий масштаб 1, увеличивается на 0.5 в секунду, пока его масштаб не достигнет 2, а затем выводит сообщение:

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

Time.deltaTime здесь работает так же, как в Update(): корутина возобновляется один раз за кадр, а строка после цикла выполняется только после его завершения. Без yield весь цикл выполняется за один кадр, и воздушный шар сразу становится полностью надутым. Цикл while (true) подходит для корутины, если на каждой итерации он приостанавливается с помощью yield; без yield он никогда не вернёт управление кадру, и редактор Unity зависнет.

challenge icon

Задание

Легко

Напиши Ride, чтобы подъёмная решётка совершила полный цикл.

  1. Задай Vector3 up = down + Vector3.up * height;. Пока while (transform.position != up), перемещай её с помощью Vector3.MoveTowards(transform.position, up, speed * Time.deltaTime) и выполняй yield return null;.
  2. Выведи в журнал Open, затем выполни yield return new WaitForSeconds(1f);.
  3. Тем же способом перемести её обратно вниз, к down, затем выведи в журнал Closed.

Нажми «Играть» и нажми пробел: ворота поднимутся, подождут и закроются. Затем нажми «Проверить».

Попробуйте сами

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()
    {
        // Поднимись на height единиц со скоростью speed и выведи в лог Open, подожди 1 секунду, опустись обратно и выведи в лог Closed
        yield return null;
    }
}

Все уроки раздела Физика и игровой процесс

Потренируйтесь самостоятельно: Песочница Unity