Unity C#

Метод Update в Unity C#: как работает и когда вызывается

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

Как устроен вызов

  • Каждый кадр, если компонент включён (enabled = true).
  • Вызывается после всех обработчиков событий (OnEnable, Start и прочих) и перед LateUpdate.
  • Частота вызова зависит от FPS: при 30 кадрах в секунду Update отработает 30 раз, при 120 — 120.
  • Unity подчёркивает: не каждому скрипту нужен Update. Пустая функция Update — это расходы на вызов каждый кадр.

Пример: движение с учётом частоты кадров

Главная ловушка Update — зависимость от FPS. Без умножения на Time.deltaTime объект проходит разный путь на 30 и на 120 FPS:

using UnityEngine;

public class Mover : MonoBehaviour
{
    public float speed = 5f;

    void Update()
    {
        // НЕПРАВИЛЬНО: скорость зависит от FPS
        // transform.Translate(Vector3.forward * speed * Time.deltaTime);

        // ПРАВИЛЬНО: путь за секунду фиксирован
        float step = speed * Time.deltaTime;
        transform.Translate(Vector3.forward * step);
    }
}

Time.deltaTime — это интервал в секундах между прошлым и текущим кадром. Умножая на него, вы переходите от «на сколько за кадр» к «на сколько в секунду».

Пример: опрос ввода

using UnityEngine;

public class PlayerInput : MonoBehaviour
{
    public float moveSpeed = 6f;

    void Update()
    {
        // Ось Horizontal: A/D, стрелки, геймпад
        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");

        Vector3 dir = new Vector3(h, 0f, v);
        transform.position += dir * moveSpeed * Time.deltaTime;

        // Мгновенный клик — проверяем каждый кадр
        if (Input.GetMouseButtonDown(0))
        {
            Debug.Log("Клик");
        }
    }
}

Порядок выполнения в кадре

Из документации Unity, упрощённая последовательность для одного кадра:

Этап Что происходит
Awake / OnEnable / Start Инициализация (однократно)
FixedUpdate Физика, вызывается с постоянным интервалом, может не вызваться в кадр или вызываться несколько раз
Update Игровая логика, ввод
LateUpdate Камера и логика, зависящая от Update всех объектов
Отрисовка Рендеринг кадра

Порядок вызова Update между разными объектами не определён и может меняться. Полагаться на «мой Update отработает раньше твоего» нельзя — для таких зависимостей порядок вызова задаётся в настройках проекта.

Update и физика: где что делать

  • Работа с Rigidbody, силами, коллизиями — в FixedUpdate, с интервалом Time.fixedDeltaTime (по умолчанию 0.02 секунды).
  • Движение через transform без физики — в Update.
  • Код, который должен отработать после всех Update всех объектов — в LateUpdate.

Частые ошибки

1. Забытый Time.deltaTime

Классика: на компьютере разработчика 120 FPS и всё «летает», у тестировщика 30 FPS — объект ползёт. Всё, что двигает объект за время, обязано умножаться на deltaTime.

3. Дорогие вызовы каждый кадр

GameObject.Find, GetComponent, аллокации строк через конкатенацию в Update — путь к просадке FPS. Кэшируйте ссылки в Awake, строковые аллокации убирайте в логику, которая вызывается по событию.

4. Пустой Update

Если тело метода закомментировано — удалите метод. Unity вызывает его каждый кадр даже пустым.

5. Логика камеры в Update

Камера, следящая за объектом, должна считать позицию после того, как все объекты обновились в Update — иначе картинка отстаёт на кадр. Для этого есть LateUpdate.

Связанные статьи