Циклы в корутинах
Часть раздела Физика и игровой процесс путешествия по 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 зависнет.
Задание
ЛегкоНапиши Ride, чтобы подъёмная решётка совершила полный цикл.
- Задай
Vector3 up = down + Vector3.up * height;. Покаwhile (transform.position != up), перемещай её с помощьюVector3.MoveTowards(transform.position, up, speed * Time.deltaTime)и выполняйyield return null;. - Выведи в журнал
Open, затем выполниyield return new WaitForSeconds(1f);. - Тем же способом перемести её обратно вниз, к
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;
}
}
Все уроки раздела Физика и игровой процесс
1Твёрдое тело
Гравитация и массаТолкаем с помощью AddForceПрыжок с импульсомFixedUpdate для физикиСкоростьКинематические телаПовторение: пусковая площадка4Корутины
InvokeInvokeRepeating, CancelInvokeВаша первая корутинаЦиклы в корутинахОстановка корутинПовторение: обратный отсчёт10Проект: Побег с арены
АренаОхотники2Столкновения
OnCollisionEnterВо что я попал?Разрушение при столкновенииСтояние на землеОтскок и трениеФормы коллайдеровПовторение: разрушаемая стена5Проект: Монетная гонка
Катящийся шарСобираем монетыПотренируйтесь самостоятельно: Песочница Unity