Menu
CoddyTech

FixedUpdate dla fizyki

Część sekcji Fizyka i rozgrywka ścieżki Unity w Coddy. Lekcja 4 z 71.

Unity porusza ciałami 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 przez pewien czas umieszczaj w FixedUpdate(). A GetKeyDown ma wartość true tylko przez jedną klatkę; jeśli w tej klatce nie ma kroku fizyki, FixedUpdate() 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 po kliknięciu wykonuje gwałtowny ruch w bok:

private bool dashQueued;

void Update()
{
    if (Input.GetMouseButtonDown(0))
    {
        dashQueued = true;   // zapamiętaj kliknięcie
    }
}

void FixedUpdate()
{
    rb.AddForce(Vector3.forward * wind);   // stały popych przy każdym kroku
    if (dashQueued)
    {
        rb.AddForce(Vector3.right * 4f, ForceMode.Impulse);
        dashQueued = false;   // jedno kliknięcie, jeden zryw
    }
}

Ważne jest, aby po użyciu wyzerować wartość bool: jeśli pozostanie true, łódź będzie wykonywać gwałtowny ruch przy każdym kroku. Pojedynczy impuls można też dodać bezpośrednio z Update(), tak jak w przypadku skoku żaby; bool pozwala trzymać wszystkie pchnięcia w jednym miejscu, obok sił, z którymi współdziała. Przytrzymane klawisze (GetKey, GetAxis) opisują stan, a nie chwilę, więc FixedUpdate() może odczytywać je bezpośrednio. Wewnątrz FixedUpdate() Time.deltaTime zwraca wartość 0.02 dla tego kroku.

challenge icon

Wyzwanie

Łatwy

Umieść dwa zadania sań we właściwych metodach.

  1. Przenieś dwa bloki if obsługujące strzałki z Update() do FixedUpdate().
  2. Dodaj private bool hopPressed;. W Update() ustaw tę zmienną na true po naciśnięciu Input.GetKeyDown(KeyCode.Space).
  3. W FixedUpdate(), gdy ustawiona jest zmienna hopPressed, dodaj impuls, a następnie ustaw ją na false.

Naciśnij „Graj”: strzałki równomiernie popychają sanki, a każde naciśnięcie klawisza spacji powoduje podskok. Następnie naciśnij „Sprawdź”.

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);
        }
    }
}

Wszystkie lekcje w sekcji Fizyka i rozgrywka

Poćwicz samodzielnie: Edytor online Unity