Использование инструкций yield
Ключевые слова yield return и следующие за ними инструкции необходимы для того, чтобы определить, какое время будет ожидать корутина до своего следующего вызова. Для примера, возьмем код из предыдущего раздела:
while (true)
{
yield return new WaitForSeconds(1);
seconds++;
Debug.Log(seconds);
}
Такой цикл будет выполняться бесконечное количество раз до остановки программы, но один раз в секунду. При этом ключевые слова yield return здесь являются “точкой ожидания”, а последующие инструкции указывают “время ожидания”
Список встроенных инструкций для yield
Существует несколько встроенных инструкций ожидания:
yield return null
- корутина ожидает конца кадраyield return new WaitForEndOfFrame();
- корутина ожидает конца кадраyield return new WaitForFixedUpdate();
- корутина ожидает до кадра, в котором рассчитывается физикаyield return new WaitForSeconds(float timeInSeconds);
- корутина ожидает времяtime
, указанное в секундах с учетомtime-scale
yield return new WaitForSecondsRealtime(float timeInSeconds);
- корутина ожидает время `time`, указанное в секундах без учетаtime-scale
yield break
- прерывает выполнение корутины
Кастомные инструкции yield
Помимо встроенных инструкций, вы можете ожидать выполнение другого корутинного метода
Например, у вас есть метод, который должен выполнить следующую последовательность действий:
- Плавно переместить объект из точки A в точку B за
- После завершения перемещения запустить салют в точке B
Такой метод можно сделать при помощи корутин
[Action(English: "Move", Russian: "Переместить")]
[ArgsFormat(English: "from {%} to {%} in {%} sec.", Russian: "из {%} в {%} за {%} сек.")]
public IEnumerator MoveAndFirework(Vector3 pointA, Vector3 pointB, float duration)
{
// Ожидаем, пока не выполнится метод MoveFromAToB.
yield return StartCoroutine(MoveFromAToB(pointA, pointB, duration));
// запускаем фейерверк
StartFirework();
}
private IEnumerator MoveFromAToB(Vector3 pointA, Vector3 pointB, float duration)
{
float time = 0f;
while (time < duration)
{
transform.position = Vector3.Lerp(pointA, pointB, time / duration);
time += Time.deltaTime;
yield return new WaitForEndOfFrame();
}
transform.position = pointB;
}
private void StartFirework()
{
//Код запуска фейерверка
}
Для корректной работы ожидания, вызов корутинного метода должен быть сделан через команду StartCoroutine
Оптимизация
Так как все встроенные yield
инструкции являются классами, то для оптимизации работы с памятью, лучше создавать экземпляры инструкций ожидания до входа в цикл
WaitForSeconds waitForSeconds = new WaitForSeconds(1f);
while(true)
{
Debug.Log("Секунда прошла");
yield return waitForSeconds;
}