Menu
CoddyTech

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.

challenge icon

Wyzwanie

Łatwy

Sanie 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 typu bool o nazwie hopPressed; w FixedUpdate() 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);
        }
    }
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Fizyka i rozgrywka