Working with Update & FixedUpdate
Unity runs on two clocks: Update runs once per rendered frame (a variable rate), and FixedUpdate runs at a fixed rate for physics. Most jitter, missed inputs and "physics feels different on my friend's PC" bugs come from mixing them up. This guide explains how they relate and what belongs where.
A film crew with two people. The camera operator (Update) takes a photo whenever they're ready: sometimes 30 per second, sometimes 144. The drummer (FixedUpdate) keeps a strict beat of exactly 50 per second no matter what. Physics dances to the drummer's beat. If you tell the dancer to move on camera clicks instead, the dance speeds up and slows down with the camera.
How the two loops line up
With the default fixed timestep of 0.02 s (50 steps per second):
Update.So FixedUpdate may run several times in one frame, or not at all.
What Unity does each frame
- Adds the real time since the last frame to an internal "accumulator".
- While the accumulator holds at least one
fixedDeltaTime: run everyFixedUpdate, step the physics simulation, send collision/trigger messages, then subtract onefixedDeltaTime. - Run every
Update, then coroutines, animations andLateUpdate. - Render the frame.
If a frame takes very long (a loading hitch), the number of catch-up physics steps is capped by Project Settings > Time > Maximum Allowed Timestep (default ⅓ s). Without that cap, a slow frame would cause many physics steps, making the next frame slow too: a "spiral of death".
What goes where
| Task | Where | Why |
|---|---|---|
| Reading input | Update | "Pressed this frame" is only true for one frame; FixedUpdate might skip it |
AddForce, setting linearVelocity, MovePosition | FixedUpdate | Physics steps at a fixed rate; applying forces per frame makes them frame-rate dependent |
| One-off impulse (jump, explosion) | Either, but buffer it into FixedUpdate | Consistent timing with the physics step |
| Moving objects without a Rigidbody | Update with Time.deltaTime | Smooth on every frame |
| Timers, cooldowns, UI, game logic | Update | Runs every frame |
| Camera follow | LateUpdate | Everything else has moved already |
| Raycasts for gameplay (shooting) | Update | React immediately |
| Raycasts that drive physics (suspension, hover) | FixedUpdate | Must match physics steps |
Pattern: read in Update, apply in FixedUpdate
using UnityEngine;
public class RollingBall : MonoBehaviour
{
[SerializeField] private float moveForce = 20f;
[SerializeField] private float jumpImpulse = 6f;
private Rigidbody rb;
private Vector3 moveInput; // continuous input: just overwrite each frame
private bool jumpQueued; // one-off input: set in Update, consume in FixedUpdate
void Awake() { rb = GetComponent<Rigidbody>(); }
void Update()
{
moveInput = new Vector3(Input.GetAxisRaw("Horizontal"), 0f, Input.GetAxisRaw("Vertical")).normalized;
if (Input.GetButtonDown("Jump")) jumpQueued = true; // never set back to false here
}
void FixedUpdate()
{
rb.AddForce(moveInput * moveForce, ForceMode.Force); // continuous: every step
if (jumpQueued)
{
rb.AddForce(Vector3.up * jumpImpulse, ForceMode.Impulse); // once
jumpQueued = false; // consumed
}
}
}
Why a flag instead of calling AddForce directly in Update? At 144 FPS, most frames have no physics step, so the force would sit waiting anyway. At 20 FPS, several physics steps happen per frame, and a force added in Update only affects the first of them. Buffering makes behavior identical at any frame rate.
deltaTime in each method
| Inside | Time.deltaTime returns |
|---|---|
Update / LateUpdate | Time since the last frame (varies) |
FixedUpdate | Time.fixedDeltaTime (e.g. 0.02), automatically |
So a function using Time.deltaTime works correctly in either. Remember that forces and velocities are already "per second": don't multiply AddForce or linearVelocity by deltaTime.
Fixing jitter: interpolation
At 144 FPS with 50 physics steps, a Rigidbody only moves on ~1 in 3 frames. The camera moves every frame. The result: the object looks like it stutters.
- Set the Rigidbody's Interpolate to Interpolate. Unity then smooths the Transform between the last two physics positions every frame. (Costs a little; use it on the player and anything the camera follows.)
- Move the camera in
LateUpdate, following the Transform (which is interpolated), notrb.position(which isn't). - Never move the same object from both loops (e.g. Rigidbody in FixedUpdate and
transform.positionin Update).
Interpolation is a flipbook artist drawing extra in-between pages. Physics only gives you a few key drawings per second; interpolation fills in the frames between them so the motion looks smooth.
Changing the fixed timestep
Project Settings > Time > Fixed Timestep (or Time.fixedDeltaTime in code).
| Value | Steps/s | Effect |
|---|---|---|
| 0.02 (default) | 50 | Good for most games |
| 0.01 | 100 | More precise (racing, fast collisions), double the physics CPU cost |
| 0.0333 | 30 | Cheaper; OK for slow-paced games and mobile |
For slow motion, scale both: Time.timeScale = 0.25f; Time.fixedDeltaTime = 0.02f * Time.timeScale;. Reset both afterwards.
Advanced: many objects, one Update
Every MonoBehaviour Update is a call from Unity's engine (C++) into your C# code. With thousands of objects, that overhead adds up. A common industry pattern is a single update manager that loops over plain C# objects:
using System.Collections.Generic;
using UnityEngine;
public interface ITickable { void Tick(float dt); }
public class TickManager : MonoBehaviour
{
private static readonly List<ITickable> tickables = new List<ITickable>();
public static void Register(ITickable t) => tickables.Add(t);
public static void Unregister(ITickable t) => tickables.Remove(t);
void Update()
{
float dt = Time.deltaTime;
for (int i = tickables.Count - 1; i >= 0; i--) // backwards: safe if one unregisters
tickables[i].Tick(dt);
}
}
public class Drone : MonoBehaviour, ITickable
{
void OnEnable() { TickManager.Register(this); }
void OnDisable() { TickManager.Unregister(this); }
public void Tick(float dt) { transform.Rotate(0f, 90f * dt, 0f); }
}
Only worth it for large numbers (hundreds to thousands) of per-frame objects. Measure with the Profiler before and after.
Staggering expensive work
// Each enemy thinks every 5th frame, spread out so they don't all think on the same frame.
private int slot;
void Awake() { slot = Random.Range(0, 5); }
void Update()
{
Move(); // cheap: every frame
if (Time.frameCount % 5 == slot) Think(); // expensive: 1 in 5 frames
}
Common Mistakes
- Input in FixedUpdate → missed presses at high frame rates.
- Continuous forces in Update → movement speed changes with frame rate.
- Moving a Rigidbody with Transform → teleporting, tunneling, jitter.
- Camera in Update or FixedUpdate following a physics object → jitter. Use LateUpdate + Interpolate.
- Counting on FixedUpdate every frame for timers → wrong at high FPS. Use Update for timers.
- Setting fixedDeltaTime very small "for accuracy" → physics eats the CPU, especially on mobile.
See also
This page is a simplified, AI-assisted interpretation. For the complete and authoritative reference, see the official Unity documentation.