FixedUpdate for Physics
Part of the Physics and Gameplay section of Coddy's Unity journey. Lesson 4 of 71.
Unity moves bodies in fixed physics steps of 0.02 seconds (Time.fixedDeltaTime), 50 a second, whatever the frame rate. FixedUpdate() runs right before each step. Update() runs once per drawn frame, and that can be 30, 60 or 144 times a second: at 144, most frames have no physics step at all, and on a slow computer one frame can hold two.
Two rules follow. A force added in Update() is added once per frame, so a faster computer pushes harder: forces that act over time go in FixedUpdate(). And GetKeyDown is true for one frame only; if that frame has no physics step, FixedUpdate() never sees it and the press is lost. So read presses in Update(), remember them in a bool, and act on them in FixedUpdate(). This boat is pushed by a steady wind and dashes sideways on a click:
private bool dashQueued;
void Update()
{
if (Input.GetMouseButtonDown(0))
{
dashQueued = true; // remember the click
}
}
void FixedUpdate()
{
rb.AddForce(Vector3.forward * wind); // a steady push, every step
if (dashQueued)
{
rb.AddForce(Vector3.right * 4f, ForceMode.Impulse);
dashQueued = false; // one click, one dash
}
}Clearing the bool after using it matters: left true, it would dash on every step. A single impulse could also be added straight from Update(), as the frog's jump was; the bool keeps every push in one place, next to the forces it works with. Held keys (GetKey, GetAxis) describe a state rather than a moment, so FixedUpdate() can read them directly. Inside FixedUpdate(), Time.deltaTime returns the step's 0.02.
Challenge
EasyPut the sled's two jobs in the right methods.
- Move the two arrow
ifblocks fromUpdate()intoFixedUpdate(). - Add
private bool hopPressed;. InUpdate(), set it totrueonInput.GetKeyDown(KeyCode.Space). - In
FixedUpdate(), whenhopPressedis set, add the impulse, then set it tofalse.
Press Play: the arrows push evenly, and every Space hops. Then Check.
Try it yourself
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);
}
}
}
All lessons in Physics and Gameplay
1Rigidbody
Gravity and MassPush with AddForceJump with an ImpulseFixedUpdate for PhysicsVelocityKinematic BodiesRecap: Launch Pad4Coroutines
InvokeInvokeRepeating, CancelInvokeYour First CoroutineLoops in CoroutinesStopping CoroutinesRecap: Countdown10Project: Arena Escape
The ArenaHunters2Collisions
OnCollisionEnterWhat Did I Hit?Break on ImpactStanding on the GroundBounce and FrictionCollider ShapesRecap: Breakable WallPractice on your own: Unity playground