FixedUpdate для физики
Часть раздела Физика и игровой процесс путешествия по Unity на Coddy. Урок 4 из 63.
Unity перемещает тела фиксированными шагами физики по 0.02 секунды (Time.fixedDeltaTime), 50 раз в секунду, независимо от частоты кадров. FixedUpdate() выполняется непосредственно перед каждым шагом. Update() выполняется один раз за каждый отрисованный кадр, а таких кадров может быть 30, 60 или 144 в секунду: при 144 кадрах в секунду на большинстве кадров шаг физики вообще не выполняется, а на медленном компьютере в одном кадре могут уместиться два шага.
Отсюда следуют два правила. Сила, добавленная в Update(), добавляется один раз за кадр, поэтому более быстрый компьютер толкает сильнее: силы, действующие на протяжении времени, добавляй в FixedUpdate(). А GetKeyDown имеет значение true только в течение одного кадра; если в этот кадр шаг физики не выполняется, FixedUpdate() его не увидит, и нажатие будет потеряно. Поэтому считывай нажатия в Update(), сохраняй их в bool и обрабатывай в FixedUpdate(). Эту лодку толкает постоянный ветер, а при щелчке она делает рывок вбок:
private bool dashQueued;
void Update()
{
if (Input.GetMouseButtonDown(0))
{
dashQueued = true; // запомнить нажатие
}
}
void FixedUpdate()
{
rb.AddForce(Vector3.forward * wind); // постоянный толчок на каждом шаге
if (dashQueued)
{
rb.AddForce(Vector3.right * 4f, ForceMode.Impulse);
dashQueued = false; // одно нажатие — один рывок
}
}Важно сбросить значение bool после его использования: если оставить true, лодка будет делать рывок на каждом шаге. Одиночный импульс также можно добавить прямо из Update(), как это было сделано с прыжком лягушки; bool позволяет держать все толчки в одном месте, рядом с силами, с которыми он работает. Удерживаемые клавиши (GetKey, GetAxis) описывают состояние, а не отдельный момент, поэтому FixedUpdate() может считывать их напрямую. Внутри FixedUpdate() Time.deltaTime возвращает значение 0.02 для этого шага.
Задание
ЛегкоУ саней на замёрзшем озере обе задачи выполняются не в тех методах. Стрелки толкают их в Update(), поэтому на более быстрых компьютерах они толкаются сильнее. Нажатие пробела заставляет их подпрыгнуть с импульсом в FixedUpdate(), поэтому некоторые нажатия ничего не делают.
- Перенеси обработку стрелок в
FixedUpdate(). - Считывай нажатие пробела в
Update()в переменную типаboolс именемhopPressed; вFixedUpdate()подпрыгивай, если она установлена, а затем сбрасывай её.
Нажми Play и попробуй оба варианта, затем нажми Check.
Попробуйте сами
using UnityEngine;
public class Sled : MonoBehaviour
{
public float push = 6f;
public float hop = 5f;
private Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void Update()
{
if (Input.GetKey(KeyCode.RightArrow))
{
rb.AddForce(Vector3.right * push);
}
if (Input.GetKey(KeyCode.LeftArrow))
{
rb.AddForce(Vector3.left * push);
}
}
void FixedUpdate()
{
if (Input.GetKeyDown(KeyCode.Space))
{
rb.AddForce(Vector3.up * hop, ForceMode.Impulse);
}
}
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Физика и игровой процесс
1Твёрдое тело
Гравитация и массаТолкаем с помощью AddForceПрыжок с импульсомFixedUpdate для физикиСкоростьКинематические телаПовторение: пусковая площадка2Столкновения
OnCollisionEnterВо что я попал?Разрушение при столкновенииСтояние на землеОтскок и трениеФормы коллайдеровПовторение: разрушаемая стена5Проект: Погоня за монетами
Катящийся мячМонеты для сбора