Menu
CoddyTech

FixedUpdate für Physik

Teil des Abschnitts Physik und Gameplay der Unity-Journey von Coddy. Lektion 4 von 63.

Unity bewegt Körper in festen Physikschritten von 0.02 Sekunden (Time.fixedDeltaTime), 50-mal pro Sekunde, unabhängig von der Bildrate. FixedUpdate() wird direkt vor jedem Schritt ausgeführt. Update() wird einmal pro gerendertem Frame ausgeführt, und das kann 30-, 60- oder 144-mal pro Sekunde sein: Bei 144 haben die meisten Frames überhaupt keinen Physikschritt, und auf einem langsamen Computer kann ein Frame zwei enthalten.

Daraus folgen zwei Regeln. Eine in Update() hinzugefügte Kraft wird einmal pro Frame hinzugefügt, sodass ein schnellerer Computer stärker schiebt: Kräfte, die über einen Zeitraum wirken, gehören in FixedUpdate(). Und GetKeyDown ist nur für einen Frame true; wenn in diesem Frame kein Physikschritt stattfindet, bekommt FixedUpdate() es nie mit und der Tastendruck geht verloren. Lies Tastendrücke daher in Update() aus, speichere sie in einem bool und reagiere in FixedUpdate() darauf. Dieses Boot wird von einem gleichmäßigen Wind angetrieben und weicht bei einem Klick seitlich aus:

private bool dashQueued;

void Update()
{
    if (Input.GetMouseButtonDown(0))
    {
        dashQueued = true;   // den Klick merken
    }
}

void FixedUpdate()
{
    rb.AddForce(Vector3.forward * wind);   // ein gleichmäßiger Schub, bei jedem Schritt
    if (dashQueued)
    {
        rb.AddForce(Vector3.right * 4f, ForceMode.Impulse);
        dashQueued = false;   // ein Klick, ein Dash
    }
}

Es ist wichtig, den booleschen Wert nach seiner Verwendung zurückzusetzen: Bliebe er true, würde das Boot bei jedem Schritt ausweichen. Ein einzelner Impuls könnte auch direkt aus Update() hinzugefügt werden, so wie es beim Sprung des Froschs war; mit dem booleschen Wert bleiben alle Schübe an einer Stelle, neben den Kräften, mit denen er zusammenwirkt. Gedrückte Tasten (GetKey, GetAxis) beschreiben einen Zustand und keinen Zeitpunkt, daher kann FixedUpdate() sie direkt auslesen. Innerhalb von FixedUpdate() gibt Time.deltaTime die Länge des Schritts von 0.02 zurück.

challenge icon

Aufgabe

Einfach

Der Schlitten auf dem gefrorenen See erledigt beide Aufgaben in der falschen Methode. Die Pfeiltasten schieben ihn in Update() an, sodass er auf schnelleren Computern stärker angeschoben wird. Mit der Leertaste springt er in FixedUpdate() mit einem Impuls, sodass manche Tastendrücke nichts bewirken.

  • Verschiebe das Anschieben mit den Pfeiltasten nach FixedUpdate().
  • Lies die Leertaste in Update() in eine bool-Variable namens hopPressed ein; springe in FixedUpdate(), wenn sie gesetzt ist, und setze sie dann zurück.

Drücke Spielen und probiere beides aus, dann Überprüfen.

Probier es selbst

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 iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Physik und Gameplay