FixedUpdate dla fizyki
Część sekcji Fizyka i rozgrywka ścieżki Unity w Coddy. Lekcja 4 z 63.
Unity przesuwa ciała w stałych krokach fizyki trwających 0.02 sekundy (Time.fixedDeltaTime), 50 razy na sekundę, niezależnie od liczby klatek na sekundę. FixedUpdate() uruchamia się tuż przed każdym krokiem. Update() uruchamia się raz na każdą renderowaną klatkę, a tych może być 30, 60 lub 144 na sekundę: przy 144 większość klatek nie obejmuje żadnego kroku fizyki, a na wolnym komputerze jedna klatka może obejmować dwa.
Wynikają z tego dwie zasady. Siła dodana w Update() jest dodawana raz na klatkę, więc szybszy komputer popycha mocniej: siły działające w czasie dodawaj w FixedUpdate(). A GetKeyDown ma wartość true tylko przez jedną klatkę; jeśli w tej klatce nie ma kroku fizyki, FixedUpdate() w ogóle tego nie zauważy i naciśnięcie zostanie utracone. Dlatego odczytuj naciśnięcia w Update(), zapamiętuj je w bool i reaguj na nie w FixedUpdate(). Tę łódź popycha stały wiatr, a kliknięcie powoduje jej boczny zryw:
private bool dashQueued;
void Update()
{
if (Input.GetMouseButtonDown(0))
{
dashQueued = true; // zapamiętaj kliknięcie
}
}
void FixedUpdate()
{
rb.AddForce(Vector3.forward * wind); // stałe pchnięcie przy każdym kroku
if (dashQueued)
{
rb.AddForce(Vector3.right * 4f, ForceMode.Impulse);
dashQueued = false; // jedno kliknięcie, jeden doskok
}
}Ważne jest, by po użyciu wyczyścić wartość bool: gdyby pozostała true, łódź wykonywałaby zryw na każdym kroku. Pojedynczy impuls można też dodać bezpośrednio z Update(), tak jak w przypadku skoku żaby; zmienna bool pozwala trzymać wszystkie pchnięcia w jednym miejscu, obok sił, z którymi współdziała. Przytrzymywane klawisze (GetKey, GetAxis) opisują stan, a nie pojedynczy moment, więc FixedUpdate() może odczytywać je bezpośrednio. Wewnątrz FixedUpdate() Time.deltaTime zwraca wartość 0.02 dla danego kroku.
Wyzwanie
ŁatwySanie na zamarzniętym jeziorze wykonują oba zadania w niewłaściwej metodzie. Strzałki popychają je w Update(), więc na szybszych komputerach są popychane mocniej. Spacja powoduje skok z impulsem w FixedUpdate(), więc niektóre naciśnięcia nie wywołują żadnej reakcji.
- Przenieś popychanie strzałkami do
FixedUpdate(). - Odczytuj naciśnięcie spacji w
Update()do zmiennej typuboolo nazwiehopPressed; wFixedUpdate()wykonaj skok, gdy zmienna jest ustawiona, a następnie ją wyczyść.
Naciśnij Play i wypróbuj oba sposoby, a następnie Check.
Spróbuj swoich sił
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);
}
}
}
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Fizyka i rozgrywka
1Ciało sztywne
Grawitacja i masaPopychanie za pomocą AddForceSkok z impulsemFixedUpdate dla fizykiPrędkośćCiała kinematycznePowtórka: platforma startowa2Kolizje
OnCollisionEnterW co uderzyłem?Rozbijanie przy zderzeniuStanie na podłożuOdbicie i tarcieKształty colliderówPodsumowanie: Zniszczalny mur