Какие yield инструкции в корутинах вы знаете?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
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, от простых задержек до управления последовательностями асинхронных операций. Понимание их различий позволяет оптимизировать код и избегать типичных ошибок, связанных с временными масштабами и зависимостью от кадров.