Метод 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.