← Назад к вопросам

Какие yield инструкции в корутинах вы знаете?

2.0 Middle🔥 291 комментариев
#C# и ООП#Асинхронность и многопоточность

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI7 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Yield инструкции в корутинах Unity

В Unity корутины (Coroutines) — это специальные методы, возвращающие IEnumerator, которые позволяют выполнять код асинхронно или с задержками без блокировки основного потока. Ключевым элементом корутин являются yield инструкции, которые определяют момент "возврата управления" и условия продолжения выполнения. Вот основные типы yield инструкций, которые я использую в разработке на протяжении более 10 лет.

Основные yield инструкции

1. yield return null

Позволяет корутине продолжить выполнение на следующем кадре (после следующего вызова Update).

IEnumerator ExampleCoroutine()
{
    while (true)
    {
        Debug.Log("Выполняется каждый кадр");
        yield return null; // Продолжить на следующем кадре
    }
}

2. yield return WaitForSeconds

Останавливает корутину на заданное количество секунд, используя игровое время (зависит от Time.timeScale).

IEnumerator DelayedAction()
{
    yield return new WaitForSeconds(2.5f); // Ждать 2.5 секунды
    Debug.Log("Сообщение после задержки");
}

3. yield return WaitForSecondsRealtime

Задержка на указанное количество реальных секунд, независимо от Time.timeScale. Критично для UI или меню, где нужно игнорировать масштабирование времени.

IEnumerator RealTimeDelay()
{
    yield return new WaitForSecondsRealtime(1f); // 1 реальная секунда
    OpenMenu();
}

4. yield return WaitForFixedUpdate

Продолжает выполнение после следующего вызова FixedUpdate. Используется для синхронизации с физикой.

IEnumerator PhysicsCoroutine()
{
    yield return new WaitForFixedUpdate();
    ApplyForceToRigidbody();
}

5. yield return WaitForEndOfFrame

Продолжает выполнение после завершения рендера кадра (LateUpdate и рендеринг). Часто используется для скриншотов или действий после завершения всех операций кадра.

IEnumerator CaptureScreenshot()
{
    yield return new WaitForEndOfFrame();
    TakeScreenshot();
}

6. yield return StartCoroutine

Позволяет вложить одну корутину в другую и ожидать её полного завершения. Это создает зависимые асинхронные цепочки.

IEnumerator MasterCoroutine()
{
    yield return StartCoroutine(SubCoroutine()); // Ждать завершения SubCoroutine
    Debug.Log("Подкорутина завершилась");
}

7. yield return AsyncOperation

Ожидает завершения асинхронной операции Unity, такой как AssetBundle.LoadAsync, SceneManager.LoadSceneAsync, или ResourceRequest.

IEnumerator LoadAssetAsync()
{
    ResourceRequest request = Resources.LoadAsync<Texture>("Icon");
    yield return request; // Ждать завершения загрузки
    Texture texture = request.asset as Texture;
}

8. yield return WaitUntil / WaitWhile

Условия продолжения на основе делегатов (лямбда-функций или методов).

  • WaitUntil: продолжает, когда условие становится true.
  • WaitWhile: продолжает, когда условие становится false.
IEnumerator ConditionalWait()
{
    yield return new WaitUntil(() => player.IsAlive); // Ждать пока игрок жив
    yield return new WaitWhile(() => enemy.IsActive); // Ждать пока враг не деактивирован
}

Практические аспекты и важные замечания

  • Прерывание корутин: Корутины можно остановить через StopCoroutine, но yield инструкции не имеют прямого механизма прерывания внутри себя.
  • Производительность: Создание новых объектов yield (например, new WaitForSeconds) в каждом кадре может нагружать память. Для повторяющихся задержек рекомендуется кэшировать объекты.
  • Связь с жизненным циклом: Если объект уничтожается (Destroy), его корутины автоматически прекращаются, что может привести к незавершенным операциям.
  • Кадровые yield: yield return null или WaitForFixedUpdate эффективны для задач, синхронизированных с циклом обновления игры.

Эти инструкции формируют основу для создания сложного асинхронного поведения в Unity, от простых задержек до управления последовательностями асинхронных операций. Понимание их различий позволяет оптимизировать код и избегать типичных ошибок, связанных с временными масштабами и зависимостью от кадров.