Menu
CoddyTech

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 icon

Challenge

Easy

Put the sled's two jobs in the right methods.

  1. Move the two arrow if blocks from Update() into FixedUpdate().
  2. Add private bool hopPressed;. In Update(), set it to true on Input.GetKeyDown(KeyCode.Space).
  3. In FixedUpdate(), when hopPressed is set, add the impulse, then set it to false.

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

Practice on your own: Unity playground