Menu
CoddyTech

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

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

Цикл с 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

Задание

Легко

Нажатие Space запускает сопрограмму Ride ворот замка Portcullis. Напиши Ride так, чтобы ворота совершили полный цикл:

  • Они поднимаются на height (3) единицы со скоростью speed (1.5) единицы в секунду, точно останавливаются наверху и выводят в журнал Open.
  • Они остаются открытыми 1 секунду.
  • Они опускаются с той же скоростью до исходного положения (down) и выводят в журнал Closed.

Нажми Play, затем нажми Space, а после этого — Check.

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

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;
    }
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

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