Coroutine в Unity: полное руководство с примерами

Подробное руководство по Coroutine в Unity: как работают корутины, что делает yield return и когда использовать WaitForSeconds, WaitUntil и другие инструкции ожидания.

Coroutine в Unity: полное руководство с примерами

Практически в любом Unity-проекте рано или поздно возникает задача выполнить действие с задержкой, постепенно изменить значение или дождаться наступления какого-либо события. Многие новички пытаются решить такие задачи через метод Update(), хотя для этого в Unity существует более удобный инструмент - Coroutine.

В этой статье разберём, что такое Coroutine, как они работают, когда их стоит использовать и каких ошибок лучше избегать.

Что такое Coroutine

Coroutine (корутина) - это специальный метод, который может приостанавливать своё выполнение и продолжать его позже.

Проще говоря, корутина позволяет выполнять код поэтапно, не блокируя основной поток игры.

Простейший пример:

using System.Collections;
using UnityEngine;

public class Example : MonoBehaviour
{
    private void Start()
    {
        StartCoroutine(PrintMessage());
    }

    private IEnumerator PrintMessage()
    {
        Debug.Log("Начало");

        yield return new WaitForSeconds(2);

        Debug.Log("Прошло две секунды");
    }
}

После запуска игры первое сообщение появится сразу, а второе - через две секунды.

Почему не использовать Update

Многие начинающие разработчики делают подобные проверки:

private float timer;

private void Update()
{
    timer += Time.deltaTime;

    if (timer >= 2)
    {
        Debug.Log("Прошло две секунды");
        timer = 0;
    }
}

Такой код работает, но быстро становится сложным, если подобных таймеров становится несколько.

Coroutine позволяют писать подобную логику значительно проще.

Как запустить Coroutine

Для запуска используется метод:

StartCoroutine(MyCoroutine());

Сама корутина должна возвращать IEnumerator.

private IEnumerator MyCoroutine()
{
    yield return null;
}

Что делает yield return

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

Например:

yield return null;

Означает:

Продолжить выполнение на следующем кадре.

WaitForSeconds

Самый популярный вариант использования.

yield return new WaitForSeconds(3f);

Корутина приостановится на три секунды.

Это удобно для:

  • задержек;
  • перезарядки оружия;
  • анимаций;
  • появления врагов;
  • игровых эффектов.

WaitForSecondsRealtime

Обычный WaitForSeconds зависит от Time.timeScale.

Если игра поставлена на паузу:

Time.timeScale = 0;

ожидание тоже остановится.

Если нужно ждать независимо от времени игры:

yield return new WaitForSecondsRealtime(3f);

WaitUntil

Иногда нужно дождаться выполнения условия.

Например:

yield return new WaitUntil(() => player.IsDead);

После смерти игрока выполнение продолжится автоматически.

WaitWhile

Работает наоборот.

yield return new WaitWhile(() => loading);

Корутина будет ждать, пока переменная loading остаётся равной true.

WaitForEndOfFrame

Позволяет выполнить код после завершения текущего кадра.

yield return new WaitForEndOfFrame();

Часто используется:

  • при создании скриншотов;
  • работе с UI;
  • чтении RenderTexture.

Запуск нескольких Coroutine

Можно запускать сразу несколько корутин.

StartCoroutine(SpawnEnemies());

StartCoroutine(UpdateScore());

StartCoroutine(PlayMusic());

Они будут выполняться независимо друг от друга.

Остановка Coroutine

Иногда необходимо остановить выполнение.

Например:

Coroutine reload;

private void Start()
{
    reload = StartCoroutine(Reload());
}

private void CancelReload()
{
    StopCoroutine(reload);
}

Также можно остановить сразу все корутины объекта:

StopAllCoroutines();

Использовать этот метод стоит осторожно.

Практический пример

Представим систему перезарядки.

private bool isReloading;

public void Reload()
{
    if (!isReloading)
        StartCoroutine(ReloadRoutine());
}

private IEnumerator ReloadRoutine()
{
    isReloading = true;

    yield return new WaitForSeconds(2);

    ammo = maxAmmo;

    isReloading = false;
}

Получается простой и легко читаемый код без множества таймеров.

Когда использовать Coroutine

Coroutine отлично подходят для:

  • задержек;
  • постепенных изменений;
  • появления волн врагов;
  • загрузки данных;
  • анимаций;
  • перезарядки;
  • кат-сцен;
  • диалогов.

Когда Coroutine использовать не стоит

Не стоит применять корутины:

  • для сложной игровой логики;
  • для постоянных вычислений;
  • вместо полноценной системы состояний.

В таких случаях лучше использовать отдельные классы или архитектурные решения.

Частые ошибки новичков

Запускать Coroutine каждый кадр

Плохо:

private void Update()
{
    StartCoroutine(MyCoroutine());
}

В результате каждую секунду создаются десятки новых корутин.

Забывать о завершении объекта

Если объект уничтожается:

Destroy(gameObject);

все его Coroutine автоматически прекращают работу.

Это важно учитывать при работе с загрузкой данных и сетевыми запросами.

Использовать Coroutine вместо любой логики

Coroutine - это инструмент для последовательного выполнения действий.

Они не заменяют архитектуру проекта.

Практический вывод

Coroutine позволяют писать более чистый и понятный код.

Вместо множества таймеров и проверок в Update() вы получаете последовательное выполнение действий, которое легче читать и поддерживать.

Именно поэтому корутины используются практически в каждом Unity-проекте.

Заключение

Coroutine - один из самых полезных инструментов Unity.

Освоив их, вы сможете проще реализовывать задержки, анимации, загрузку данных и множество игровых механик без лишнего усложнения кода.

Главное - использовать их по назначению и не пытаться заменить ими всю игровую логику.

Другие статьи

Dependency Injection в Unity (Zenject и VContainer) 4 просм. Dependency Injection в Unity (Zenject и VContainer)

По мере роста проекта код в Unity начинает усложняться. Скрипты становятся зависимыми друг от друга, появляется множество ссылок через Inspector, а изменения в одной системе неожиданно ломают другую. Именно для решения таких проблем используется Dependency Injection (DI). В этой статье разберём, что такое DI, зачем он нужен в Unity и какой инструмент выбрать: Zenject или VContainer.

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

Обсуждение статьи. Комментарии проходят модерацию.

RedAmmo
RedAmmo
30 июня 2026 02:06
Hello1, тоже так думаю, мне нравятся ослики
Hello1
Hello1
30 июня 2026 00:44
Hugging guvbubu