Начинаю серию постов, где детально разберу как работают методы Update и для чего они нужны.
Все эти методы являются частью жизненного цикла MonoBehaviour:
• Update вызывается каждый кадр игры.
• FixedUpdate вызывается определённый промежуток времени, который указан в настройках Юнити.
• LateUpdate вызывается после того, как все вызовы Update уже отработали. То есть, по сути, в конце кадрового цикла.
Однако, сухие определения - это конечно хорошо, но что с практикой? Когда нам может пригодиться одно, а когда другое?
Update нужен, когда у нас вызывается какая-нибудь логика, работа которой у нас должна выполняться каждый кадр.
Из тривиального - считывание нажатия игрока:
private void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
_isJumpRequested = true;
}
}
В LateUpdate мы рассчитываем логику, которая нам нужна после того, как все кадры уже просчитались.
Например, для слежения камеры за игроком. Если сделать это в Update, то наша камера будет дёрганной. Им нужна итоговая точка объекта, чтобы они его не "догоняли" или не "перегоняли".
Классический пример с камерой:
private void LateUpdate()
{
Vector3 desiredPosition = _target.position + _offset;
Vector3 smoothedPosition = Vector3.Lerp(transform.position, desiredPosition, _smoothSpeed * Time.deltaTime);
transform.position = smoothedPosition;
transform.LookAt(_target);
}
Update приводит позиции к какому-то значению, а LateUpdate выполняется после того, как все Update отработали. Камера будет очень плавно идти за игроком и не будет меняться в рандомный момент кадра, как бы она это делала, если бы была в Update.
В FixedUpdate считывание ввода или слежение камеры добавлять не стоит, так как из-за того, что FixedUpdate работает какой-то определённый константный промежуток. Мы можем пропустить нажатие игрока, а поведение камеры будет выглядеть странно.
Но зачем тогда он вообще нужен?
Этот метод используется для просчётов физики, в которой нужно, чтобы всё работало одинаково, не завися от количества кадров.
FixedUpdate имеет фиксированный timestamp.
То есть, если у нас 60 фпс - Update вызывается 60 раз. Если у нас 20 фпс - 20 раз. Это слишком нестабильно для чётких расчётов.
Timestamp в 0.02 секунды может гарантировать нам, что метод вызовется ровно 50 раз в секунду. Это стабильность. Таким образом у нас физика будет постоянной и не зависеть от такого хаотичного параметра как кадры.
Пример:
private void FixedUpdate()
{
IsGrounded = Physics2D.OverlapCircle(_groundChecker.position, _data.GroundCheckRadius, _data.GroundLayer);
if (_isJumpRequested)
{
_rigidbody2D.linearVelocityY = _data.JumpForce;
_isJumpRequested = false;
}
if (_isJumpCutRequested && _rigidbody2D.linearVelocityY > 0f)
{
_rigidbody2D.linearVelocityY *= _data.JumpCutMultiplier;
_isJumpCutRequested = false;
}
}
В следующей части мы поговорим про такую сущность как Time.deltaTime и почему она крайне необходима в контексте Update.
🚀 Пост Guru Unity: @Minerope
