Ключевые слова yield return и следующие за ними инструкции необходимы для того, чтобы определить, какое время будет ожидать корутина до своего следующего вызова. Для примера, возьмем код из предыдущего раздела:

while (true)  
{  
    yield return new WaitForSeconds(1);  
    seconds++;  
    Debug.Log(seconds);  
}
C#

Такой цикл будет выполняться бесконечное количество раз до остановки программы, но один раз в секунду. При этом ключевые слова yield return здесь являются “точкой ожидания”, а последующие инструкции указывают “время ожидания”

Список встроенных инструкций для yieldLink to Список встроенных инструкций для 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 - прерывает выполнение корутины

Кастомные инструкции yieldLink to Кастомные инструкции yield

Помимо встроенных инструкций, вы можете ожидать выполнение другого корутинного метода

Например, у вас есть метод, который должен выполнить следующую последовательность действий:

  1. Плавно переместить объект из точки A в точку B за
  2. После завершения перемещения запустить салют в точке 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()  
{  
    //Код запуска фейерверка  
}
C#

Для корректной работы ожидания, вызов корутинного метода должен быть сделан через команду StartCoroutine

Оптимизация

Так как все встроенные yield инструкции являются классами, то для оптимизации работы с памятью, лучше создавать экземпляры инструкций ожидания до входа в цикл

WaitForSeconds waitForSeconds = new WaitForSeconds(1f);  
while(true)  
{  
    Debug.Log("Секунда прошла");  
    yield return waitForSeconds;  
}
C#