So the diagram is correct, as is your understanding, except for one part:
The FixedUpdate
step can enter that loop on the diagram
- It can call
FixedUpdate
just one time
- It can call
FixedUpdate
more than once,
- Or, it can call
FixedUpdate
no times.
Why? Because framerates can vary like crazy, but FixedUpdate
should be Fixed. In your case your framerate (and therefore Update
) is running up 1000fps because it's going as fast as it can, but FixedUpdate
is just trying to hit your target physics step, probably 50 per second.
Let's look at the possibilities. Let's say your FixedUpdate
is trying to match your ideal framerate of 60
fps.
If you're lucky, and your game is running consistently at 60fps, then each frame, Unity will try run a fixed update, see that it was 1/60
s real-time since your last FixedUpdate
, and call it once. Then call Update
If your game is only running at 30fps, for whatever reason, unity will start your new frame, hit the FixedUpdate
phase and see it's been a whole 1/30
s real-time since your last FixedUpdate
and calculate that it needs to call two FixedUpdates
to catch up to that 60
per seconds. After calling FixedUpdate
twice, it will then call Update
, and repeat the process.
But, if you are lucky enough that your game is running at 120
fps, then you don't want extra FixedUpdate
calls. So, unity will reach the FixedUpdate
phase, see that its been only 1/120
s since the last update, and will call FixedUpdate
zero times, effectively skipping this phase. It will then call Update
, and only the next frame will it count the required 1/60
s since last FixedUpdate
and will call the function once. Effectively making FixedUpdate
run only every second frame.
It's important to remember that
- Unity is single threaded in this process, nothing magic is happening and nothing is happening truly in parallel.
FixedUpdate
is only guaranteed to be called the correct number of times over a period of frames. It is not guaranteed to be called exactly equidistantly in real time - it won't always happen once every x seconds realtime - only that over a period of y seconds, it will be called the correct number of times.
This last point makes sense because FixedUpdate
can't "interrupt" a long running Update
just because it's due, it just has to catch up before the next frame.