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.
Aufgabe
EinfachDer 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 einebool-Variable namenshopPressedein; springe inFixedUpdate(), 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);
}
}
}
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
1Rigidbody
Schwerkraft und MasseMit AddForce schiebenMit einem Impuls springenFixedUpdate für PhysikGeschwindigkeitKinematische KörperRückblick: Startrampe2Kollisionen
OnCollisionEnterWas habe ich getroffen?Beim Aufprall zerbrechenAuf dem Boden stehenAbprallen und ReibungCollider-FormenRückblick: Zerstörbare Wand