UPDATE VS FIXEDUPDATE VS LATEUPDATE IN UNITY
A complete engineering comparison of Unity's three core update loops, execution timing, input polling rules, and physics synchronization.
1. High-Level Comparison Summary
Primary Use: Polling player inputs (
Input.GetKeyDown), updating non-physics game timers, UI animations, and mesh rotations.Delta Time:
Time.deltaTime
Primary Use: Applying
Rigidbody.AddForce(), setting physical velocity, torque, wheel colliders, and Raycast sweeps.Delta Time:
Time.fixedDeltaTime
Update() calls finish).Primary Use: Follow cameras, third-person tracking rigs, head-look IK, and screen-space overlay clamping.
Delta Time:
Time.deltaTime
2. The Critical Pitfall: Polling Inputs in FixedUpdate
One of the most common bugs in Unity is reading Input.GetKeyDown(KeyCode.Space) inside FixedUpdate().
Because Update() runs with every screen refresh (e.g. 120 FPS = 8.3ms per frame) while FixedUpdate() runs at 50 FPS (20ms), multiple render frames can pass between physics steps. If a player taps the jump button during a frame where FixedUpdate does not tick, Unity resets the one-frame keydown flag and the jump is completely eaten!
The Solution: Always capture input flags in Update(), and consume them inside FixedUpdate():
using UnityEngine;
/// <summary>
/// Correctly synchronizes instantaneous player jump input with Rigidbody physics.
/// </summary>
public class CorrectJumpController : MonoBehaviour
{
[SerializeField] private Rigidbody rb;
[SerializeField] private float jumpForce = 8f;
private bool jumpRequested;
private float horizontalInput;
private void Awake()
{
if (rb == null) rb = GetComponent<Rigidbody>();
}
// 1. Capture inputs every frame in Update
private void Update()
{
horizontalInput = Input.GetAxisRaw("Horizontal");
if (Input.GetButtonDown("Jump"))
{
jumpRequested = true; // Store request until next physics tick
}
}
// 2. Apply physical impulses in FixedUpdate
private void FixedUpdate()
{
// Continuous movement force
rb.AddForce(new Vector3(horizontalInput * 15f, 0f, 0f), ForceMode.Force);
// Instantaneous jump impulse
if (jumpRequested)
{
rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
jumpRequested = false; // Reset request flag
}
}
}
3. Why Follow Cameras Must Use LateUpdate()
If your player moves in Update() and your camera also moves in Update(), Unity does not guarantee script execution order. In some frames, the camera will read the player's position before the player moves; in other frames, it will read it after. This creates noticeable micro-jitter and screen tearing.
Placing camera tracking in LateUpdate() guarantees the target character has completely finished moving for that frame before the camera calculates its target interpolation.
Related Topics & Troubleshooting
Frequently Asked Questions
0.02 (50 Hz). For high-precision simulation games or esports combat, setting it to 0.016666 (60 Hz) or 0.01 (100 Hz) improves collision accuracy at the cost of higher CPU consumption.
void Update() { }, Unity adds that MonoBehaviour to the engine's native update loop list. If you have 5,000 enemy or projectile objects with empty Update() methods, traversing the C++ to C# boundary causes unnecessary CPU overhead. Always delete unused default MonoBehaviour templates!