Menu
CoddyTech

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 icon

Challenge

Easy

The 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 a bool named hopPressed; in FixedUpdate(), 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);
        }
    }
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Physics and Gameplay