FixedUpdate для физики
Часть раздела Физика и игровой процесс путешествия по Unity на Coddy. Урок 4 из 71.
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.
Задание
ЛегкоРазмести две задачи саней в правильных методах.
- Перемести два блока
ifсо стрелками изUpdate()вFixedUpdate(). - Добавь
private bool hopPressed;. ВUpdate()присвой ему значениеtrueпри нажатииInput.GetKeyDown(KeyCode.Space). - В
FixedUpdate(), когда установлено значениеhopPressed, добавь импульс, а затем присвой ему значениеfalse.
Нажми «Играть»: стрелки будут равномерно толкать сани, а каждое нажатие пробела будет заставлять их подпрыгивать. Затем нажми «Проверить».
Попробуйте сами
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 для физикиСкоростьКинематические телаПовторение: пусковая площадка4Корутины
InvokeInvokeRepeating, CancelInvokeВаша первая корутинаЦиклы в корутинахОстановка корутинПовторение: обратный отсчёт10Проект: Побег с арены
АренаОхотники2Столкновения
OnCollisionEnterВо что я попал?Разрушение при столкновенииСтояние на землеОтскок и трениеФормы коллайдеровПовторение: разрушаемая стена5Проект: Монетная гонка
Катящийся шарСобираем монетыПотренируйтесь самостоятельно: Песочница Unity