0
\$\begingroup\$

The old Unity 5.3 documentation said:

Time.fixedDeltaTime

The interval in seconds at which physics and other fixed frame rate updates (like MonoBehaviour's FixedUpdate) are performed.

For reading the delta time it is recommended to use Time.deltaTime instead because it automatically returns the right delta time if you are inside a FixedUpdate function or Update function.

Note that the fixedDeltaTime interval is with respect to the in-game time affected by timeScale.

So, it was said (paraphrased as I get it) that Time.fixedDeltaTime returns the interval at which the FixedUpdate method should be called with respect to the timeScale. But the real interval could differ (for technical reasons) and that's why Time.deltaTime should be used instead to return a real time elapsed since the previous FixedUpdate call.

The latest docs don't say that anymore: https://docs.unity3d.com/ScriptReference/Time-fixedDeltaTime.html

Does it mean that now FixedUpdate is called exactly at Time.fixedDeltaTime rate?

Now it also says:

Unity does not adjust fixedDeltaTime based on Time.timeScale. The fixedDeltaTime interval is always relative to the in-game time which Time.timeScale affects.

Don't these two sentences contradict each other?

\$\endgroup\$
1

2 Answers 2

4
\$\begingroup\$

So, it was said (paraphrased as I get it) that Time.fixedDeltaTime returns the interval at which the FixedUpdate method should be called with respect to the timeScale.

Yes, it's the interval of game time between successive FixedUpdate calls.

But the real interval could differ (for technical reasons) and that's why Time.deltaTime should be used instead to return a real time elapsed since the previous FixedUpdate call.

No.

You can imagine deltaTime being implemented something like this:

public float deltaTime { get {
    if (_isCurrentlyRunningFixedUpdates) {
        return fixedDeltaTime;
    } else {
        return Mathf.Min(timeScale * _realtimeSecondsSinceLastFrame, maximumDeltaTime);
    }
} }

Basically deltaTime is a getter that returns "how much game simulation time should I treat as having passed, based on where in the update flow I am currently running?".

  • If you're in a fixed step (physics updates, FixedUpdate, collision handling messages), it gives you exactly the same value as writing fixedDeltaTime instead.

    That's the point of a fixed time step: it's fixed - it does not change no matter what weirdness might be happening with regard to wall-clock-time.

  • If you're in a variable step (Update, LateUpdate), it gives you the amount of game simulation time that's run since the last rendered frame, which could be more or less depending on your framerate, transient load spikes, etc.

The convenience of this behaviour is that if you have a function that's called in multiple places, sometimes from FixedUpdate or a collision handler and sometimes from Update, it automatically adapts itself to give the right value for that context. Or if you refactor some code and move it from one update to another, you don't need to remember to update the time step you're using, as long as you've been consistent about always reading Time.deltaTime.


It's important to remember that fixedDeltaTime is a measure of game simulation time. It is not a measure of real time.

When running a fixed update loop, the game measures the total realtime / wall clock time elapsed since the last frame, scales it by your time scale, and then divides that by your fixedDeltaTime to get an integer representing how many times it should tick the physics simulation this frame. Any fractional part is carried over as loose change to add to the calculation for next frame.

So on a short frame, you might not run the physics step or FixedUpdate at all. On a longer frame, you might run the physics step and FixedUpdate functions multiple times.

When we do tick multiple times in one frame, all those ticks are run in rapid succession back-to-back. We don't put delays in between them so that each is called one fixedDeltaTime apart from the last with regard to the wall clock. Because again, fixedDeltaTime measures game sim time, not wall clock time.

What matters is that "by the time we get to a frame \$x\$ seconds into the game, I expect \$\lfloor 50 \cdot x\rfloor\$ FixedUpdate steps have run" (if using the default 0.02 value for fixedDeltaTime and a timeScale of 1.0). So we don't get ahead the rendered frame, or fall behind it by a fixedDeltaTime or more.

When exactly in wall clock time that code ran on the CPU doesn't matter - it's not directly observable by the player, all they can see is the resulting rendered frame that gets presented after we've done all the catching-up we need to do for this frame.

There is an exception in the case where your computer just can't keep up with running the number of physics steps / FixedUpdate calls needed to keep pace: Unity provides a maximum allowable game time step. If your frame time runs so long that the game simulation it accounts for exceeds this limit, then Unity will stop running fixed steps and cap the simulation as far as it got this frame, resuming next frame. In this situation, game time slows down relative to real time until the computer is able to catch up. But each FixedUpdate call still represents exactly the same amount of game time as before.


Unity does not adjust fixedDeltaTime based on Time.timeScale. The fixedDeltaTime interval is always relative to the in-game time which Time.timeScale affects.

Don't these two sentences contradict each other?

No. What this is saying is that changing the value you put into Time.timeScale does not change the value you read from fixedDeltaTime.

By setting fixedDeltaTime to 0.02, I am saying "I want physics to tick and FixedUpdate to run exactly 50 times per second of game time". And Unity honours that.

  • If I speed up game time so it's running 2 seconds of simulation for every 1 second of real time, then Unity will run 100 physics steps for every wall clock second (still 50 per game second)

  • If I slow down my game time so it's running at half a second of simulation for every 1 second of real time, then Unity will run 25 physics steps for every wall clock second (still 50 per game second)

Time.timeScale changes the relationship between game time and real time. fixedDeltaTime is measured in game time, so this scaling does not affect it.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Thank you for such a detailed answer! I still sometimes forget that game lives in its own time sandbox. If we imagine that game is a matrix, for its inhabitants it won't be noticeable whether their time goes faster or slower (relative to the external world they don't even know about), because their whole universe (including their perception of time) works in sync with their time. \$\endgroup\$
    – Serg
    Commented May 18, 2021 at 12:15
1
\$\begingroup\$

Time.fixedDeltaTime is the interval for FixedUpdate() calls relative to scaled in-game time.

For example, if fixedDeltaTime is .02, FixedUpdate() is called 50 times a second (both real-time and in-game time) when timeScale = 1. If timescale = 2, FixedUpdate() would still be called 50 times a second in in-game time, but 100 times a second in real-time. fixedDeltaTime would still be .02 regardless of what the timeScale is.

Time.deltaTime does different things depending on when you use it:

  • If you use it during the Update() cycle, it returns the amount of time elapsed since the previous frame
  • If you use it during the FixedUpdate() cycle, it returns the same value as fixedDeltaTime.

Unity recommends always using Time.deltaTime because it returns the relevant value regardless of whether you're currently in Update() or FixedUpdate(), but if you find this confusing then you can use fixedDeltaTime for clarity.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .