As far as I understand it, the two different update functions work something like this. I'm writing it in the form of pseudocode first, and adding diagrams below, which may or may not make it clearer to understand!
In the (completely fictitious) code below, first the appropriate number of physics steps are executed in order to "catch up" with the current time (and each step, FixedUpdate() is called on each object which implements it). Next, the graphics for the frame are rendered, followed by Update() on each object which implements it.
var physicsTimeSimulated = 0;
var lastUpdateTime = 0;
while (Unity is Running)
{
while (physicsTimeSimulated < Time.time)
{
Engine.ExecutePhysicsStep();
Engine.FixedUpdate(); // <-- sent to all objects
physicsTimeSimulated += physicsTimeStep;
}
deltaTime = Time.time - lastUpdateTime;
Engine.RenderFrame();
Engine.Update(); // <-- sent to all objects
lastUpdateTime = CurrentTime;
// and repeat...
}
It's worth noting that if the game is running at a slow frame rate, there will be numerous physics updates between each visible frame render. Conversely, if the game is running at a very high frame rate, there may be no physics steps at all between some of the frame renders, because the time elapsed since the last rendered frame has not yet exceeded the time period of a single physics step.
If the physics timescale is left at its default value (0.02) this gives us 50 physics updates per second - each physics step simulates the motion that occurs over the period of two-hundredths of a second.
The diagram below shows a period of one-tenth of a second. The dots which break up the line indicate 100th's of a second.
(I'm using an "F" to show where the FixedUpdate calls go)
0 0.1 seconds
| |
.____.____.____.____.____.____.____.____.____.____.___
F F F F F F
Now, if our game were running nice and fast at 100fps, we'd have two frame renders for every physics step - and therefore two calls to our Update() functions, for every call to our FixedUpdate() functions.
(Key: "F" for FixedUpdate and "U" for Update)
0 0.1
| |
.____.____.____.____.____.____.____.____.____.____.___
F F F F F F
U U U U U U U U U U U
If our game is running slower, say - at 30 frames per second (and therefore 30 calls to all Update() functions per second), it would mean that we actually sometimes have more than one physics step between each frame render. In the case of 30 fps, the result would be that sometimes two physics steps are executed between frames, and sometimes one, which would look something like this, for the first 10th of a second:
0 0.1
| |
.____.____.____.____.____.____.____.____.____.____.___
F F F F F F
U U U U
So, in most normal circumstances, you'll always get the desired number of physics steps per frame, and interleaved with these will be the visual frame updates, at as fast a rate as possible.
It's for this reason that FixedUpdate should be used when applying forces, torques, or other physics-related functions - because you know it will be executed exactly in sync with the physics engine itself.
Whereas Update() can vary out of step with the physics engine, either faster or slower, depending on how much of a load the graphics are putting on the rendering engine at any given time, which - if used for physics - would give correspondingly variant physical effects!
The exception to this would be that if your scene was putting such a load on the physics engine that it approaches the point where it becomes impossible to execute the required number of physics time steps to keep up to speed with 'real time'. This means that your game has become impossible to simulate in real time - and in this case you need to seriously think about redesigning your game! This can happen if you have large numbers of complex objects (eg, rigidbody mesh colliders) all clumped together so you have lots of many-to-many collisions occuring each step.
Hope this sheds some light on the comings and goings of FixedUpdate and Update!