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

Объясните жизненный цикл MonoBehaviour. В каком порядке вызываются Awake, OnEnable, Start, Update, FixedUpdate, LateUpdate?

1.3 Junior🔥 211 комментариев

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

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

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

Жизненный цикл MonoBehaviour в Unity

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

Порядок выполнения ключевых методов

Порядок вызова стандартных методов MonoBehaviour определяется движком Unity и выглядит следующим образом при первом создании объекта с активным компонентом или при его активации:

  1. Awake()
  2. OnEnable()
  3. Start()
  4. FixedUpdate() (циклически, независимо от частоты кадров)
  5. Update() (циклически, на каждый кадр)
  6. LateUpdate() (циклически, после всех Update())

Детальное объяснение этапов


1. Awake()

Этот метод вызывается первым, когда экземпляр скрипта загружается в память, независимо от того, активен (enabled) объект или нет. Он вызывается даже если компонент отключен в Inspector. Это самый ранний этап инициализации.

  • Назначение: Инициализация внутренних переменных, ссылок на другие компоненты, установка структуры данных.
  • Контракт: Гарантированно вызывается один раз перед Start(). Идеальное место для подготовки, когда существование других объектов еще не гарантировано.
  • Пример использования:
public class PlayerController : MonoBehaviour
{
    private Rigidbody rb;
    private GameManager manager;

    void Awake()
    {
        // Получаем ссылку на компонент, даже если скрипт отключен
        rb = GetComponent<Rigidbody>();
        manager = FindObjectOfType<GameManager>();
    }
}

2. OnEnable()

Вызывается каждый раз, когда объект или компонент становится активным (enabled = true). Это включает момент после Awake() (если объект создается активным), а также повторную активацию объекта после его отключения.

  • Назначение: Реакция на активацию: регистрация в системах событий, запуск аудио/визуальных эффектов, включение взаимодействия.
  • Контракт: Вызывается после Awake(), но до Start() при первичной активации. Может вызываться многократно.
  • Пример:
void OnEnable()
{
    // Подписываемся на событие при активации
    EventManager.OnGamePaused += HandlePause;
}

3. Start()

Вызывается один раз (только при первой активации), непосредственно перед первым вызовом Update(), но после Awake() и OnEnable().

  • Назначение: Финальная инициализация, которая зависит от других объектов, уже завершивших свой Awake(). Например, установка начального состояния, загрузка данных из GameManager, который уже инициализировался.
  • Контракт: Гарантированно вызывается после всех Awake() на всех объектах в сцене. Только один раз.
void Start()
{
    // Теперь GameManager гарантированно инициализирован в Awake
    if(manager != null)
    {
        health = manager.GetInitialHealth();
    }
}

Циклические методы обновления (Update Loop)

После Start() начинается основной игровой цикл, который состоит из трех основных методов, вызываемых в строгом порядке на каждом проходе цикла движка.

4. FixedUpdate()

Вызывается по фиксированному таймеру, независимо от частоты кадров (frame rate). Частота определяется в Edit > Project Settings > Time > Fixed Timestep (обычно 0.02 сек = 50 раз в секунду).

  • Назначение: Все вычисления, связанные с физикой. Любое изменение Rigidbody, Transform через физические силы (AddForce) должно происходить здесь для стабильной и предсказуемой работы физического движка.
  • Контракт: Вызывается перед Update(). Периодичность фиксирована.
void FixedUpdate()
{
    // Силы применяются здесь
    rb.AddForce(movementDirection * speed, ForceMode.Acceleration);
}

5. Update()

Вызывается каждый новый кадр игры. Частота зависит от производительности (frame rate). Это самый распространенный метод для игровой логики.

  • Назначение: Ввод пользователя, нефизические перемещения, логика AI, обновление состояния игры.
  • Контракт: Вызывается после всех FixedUpdate() (если они были в этом цикле), но перед LateUpdate().
void Update()
{
    // Обработка ввода и немгновенная логика
    movementDirection = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
    if (Input.GetKeyDown(KeyCode.Space))
    {
        Jump();
    }
}

6. LateUpdate()

Вызывается после того, как все Update() на всех объектах завершились.

  • Назначение: Логика, которая зависит от завершенных вычислений в Update() других объектов. Часто используется для следования камеры за объектом, который переместился в своем Update().
  • Контракт: Гарантированный порядок: сначала все обновляют свои позиции (Update), затем камера корректирует свое положение (LateUpdate).
void LateUpdate()
{
    // Камера следят за игроком, который уже переместился в Update
    cameraTransform.position = playerTransform.position + offset;
}

Итоговая схема вызовов (первый запуск)

Awake() -> OnEnable() -> Start() -> [FixedUpdate -> Update -> LateUpdate] (цикл)

Важно помнить:

  • При отключении (enabled = false) вызывается OnDisable().
  • При уничтожении объекта вызывается OnDestroy().
  • FixedUpdate может вызываться несколько раз за один кадр (если frame rate низкий), или один раз за несколько кадров (если frame rate высокий), но его интервал времени всегда фиксирован.