FixedUpdate für Physik
Teil des Abschnitts Physik und Gameplay der Unity-Journey von Coddy. Lektion 4 von 71.
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 Schritte 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 längere Zeit wirken, gehören in FixedUpdate(). Und GetKeyDown ist nur für einen Frame lang wahr; wenn dieser Frame keinen Physikschritt hat, bekommt FixedUpdate() es nie mit und der Tastendruck geht verloren. Lies Tastendrücke also in Update() aus, speichere sie in einem bool und reagiere in FixedUpdate() darauf. Dieses Boot wird von einem stetigen Wind geschoben und saust bei einem Mausklick seitwärts:
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 Sprint
}
}Es ist wichtig, den bool nach seiner Verwendung zurückzusetzen: Ließe man ihn auf true, würde das Boot bei jedem Schritt losschießen. Ein einzelner Impuls könnte auch direkt in Update() hinzugefügt werden, wie beim Sprung des Froschs; der bool hält alle Schübe an einem Ort, neben den Kräften, mit denen er zusammenwirkt. Gedrückte Tasten (GetKey, GetAxis) beschreiben einen Zustand statt eines Moments, daher kann FixedUpdate() sie direkt auslesen. Innerhalb von FixedUpdate() gibt Time.deltaTime die Dauer des Schritts von 0.02 zurück.
Aufgabe
EinfachOrdne die beiden Aufgaben des Schlittens den richtigen Methoden zu.
- Verschiebe die beiden
if-Blöcke für die Pfeiltasten ausUpdate()nachFixedUpdate(). - Füge
private bool hopPressed;hinzu. Setze es inUpdate()beiInput.GetKeyDown(KeyCode.Space)auftrue. - Füge in
FixedUpdate(), wennhopPressedgesetzt ist, den Impuls hinzu und setze es anschließend auffalse.
Drücke auf „Spielen“: Die Pfeiltasten schieben den Schlitten gleichmäßig an, und bei jedem Druck auf die Leertaste springt er. Drücke dann auf „Prü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);
}
}
}
Alle Lektionen in Physik und Gameplay
1Rigidbody
Schwerkraft und MasseMit AddForce schiebenMit einem Impuls springenFixedUpdate für PhysikGeschwindigkeitKinematische KörperRückblick: Startrampe4Coroutinen
AufrufenWiederholt aufrufen, Aufruf abbrechenDeine erste CoroutineSchleifen in CoroutinenCoroutinen beendenRückblick: Countdown10Projekt: Arena-Flucht
Die ArenaJäger2Kollisionen
OnCollisionEnterWas habe ich getroffen?Beim Aufprall zerbrechenAuf dem Boden stehenAbprallen und ReibungCollider-FormenRückblick: Zerstörbare Wand5Projekt: Münzrausch
Der rollende BallMünzen zum Einsammeln11Abschließende Herausforderungen
KanonenreichweiteBewegliche ZieleMurmelgolfIns LochEscape RoomDie TürÜbe selbstständig: Unity-Playground