FixedUpdate for Physics
Part of the Physics and Gameplay section of Coddy's Unity journey. Lesson 4 of 63.
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
EasyThe sled on the frozen lake has both of its jobs in the wrong method. The arrows push it in Update(), so it is pushed harder on faster computers. Space hops it with an impulse in FixedUpdate(), so some presses do nothing.
- Move the arrow pushing into
FixedUpdate(). - Read Space in
Update()into aboolnamedhopPressed; inFixedUpdate(), hop when it is set, then clear it.
Press Play and try both, 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);
}
}
}
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Physics and Gameplay
1Rigidbody
Gravity and MassPush with AddForceJump with an ImpulseFixedUpdate for PhysicsVelocityKinematic BodiesRecap: Launch Pad2Collisions
OnCollisionEnterWhat Did I Hit?Break on ImpactStanding on the GroundBounce and FrictionCollider ShapesRecap: Breakable Wall