What is the reason of FixedUpdate() being invoked more than 1 time on low framerate ?

I know that FixedUpdate() runs every 0.02 sec (50 times in total for 1 second). But what if by some reason FPS will drop to 10 frames for example and will stand 10 FPS for awhile… Then FixedUpdate() will be invoked 5 times per a frame, right ? But what is the truly purpose of doing that ? Why it’s not enough to call FixedUpdate() only once in such case and discard others 4 (especially when we are talking about physics when it’s important to get the latest changes at the moment) ? I’m sure this question more suitable for the Unity engine developers. But maybe I’m missing something ? What is the reason of such behavior ? Any ideas ?

Because physics and other systems (i.e. gameplay) must use a constant delta time to be consistent. It’s not only about the number of times FixedUpdate is called per visual frame, but most importantly every call will be performed with the same delta time, by default 0.02 (50 Hz). Otherwise, these systems would be inconsistent when frame rate drops.

For example take a physics rigidbody that moves at 50 m/s, let’s say it’s a fast car. At that speed moves 1m on each physics step (FixedUpdate). Suppose the car is 4m long. At one physics frame the car can be at one side of the road guardrail, and the next frame it can be at most 1m behind the guardrail. So the physics engine can detect the collision of the car with the guardrails at that speed without issues.

What if we call FixedUpdate 10 times per second as you propose? This means a delta time of 0.1, so the car moves 5m on each physics step. At one frame it can be at one side of the guardrail, but the next frame the car may be entirely at the opposite side of the guardrail without the collision being detected.

So instead of doing so, when the visual frame rate drops Unity keeps calling FixedUpdate many times when necessary. The next visual frame will display the car after having collided properly with the guardrail. You would have lost a few visual frames and effects only, but the physics result (and the gameplay) will be the same regardless the fps. This logic is applicable to anything requiring consistency: character controller, jumps, bullets, AI, …

Here’s a quick an convenient guide about Update and FixedUpdate:

https://forum.unity.com/threads/update-vs-fixed-update-vs-late-update.307235/#post-5114657

Here’s a detailed example of physics inconsistencies when changing the fixed delta time:
https://forum.unity.com/threads/adjusting-time-fixeddeltatime-by-time-timescale.869491/#post-6796637

The point of fixedupdate is to have a constant call count per second. Any linear calculations can be framerate adjusted by using deltaTime. However Any kind of calculation that is not linear can not be compensated with deltatime. In physics when you have a constant acceleration the velocity would change linearly. Using deltaTime would result in correct velocity values each frame. However the position in turn is linearly adjusted by the velocity and indirectly by the square of the acceleration. This is never accurate. It would require an infinitely high framerate to get accurate results. This is of course not possible. Instead we ensure a framerate of 50 fps to ensure the same results independent of the framerate.

Just as an example compare the results of just using deltaTime with a framerate of 20 and a framerate of 5 compared to the physical accurate result of a contant accelerated movement:

//  t    acc        vel10    pos10    vel5     pos5     velR     posR
// --------------------------------------------------------------------
// 0.0    2          0        0        0        0        0        0
// 0.1    2          0.2      0.02                       0.2      0.01
// 0.2    2          0.4      0.06     0.4      0.08     0.4      0.04
// 0.3    2          0.6      0.12                       0.6      0,09
// 0.4    2          0.8      0.2      0.8      0.24     0.8      0.16
// 0.5    2          1.0      0.3                        1.0      0.25
// 0.6    2          1.2      0.42     1.2      0.48     1.2      0.36
// 0.7    2          1.4      0.56                       1.4      0.49
// 0.8    2          1.6      0.72     1.6      0.8      1.6      0.64
// 0.9    2          1.8      0.9                        1.8      0.81
// 1.0    2          2.0      1.1      2.0      1.2      2.0      1.0
// 1.1    2          2.2      1.32                       2.2      1.21
// 1.2    2          2.4      1.56     2.4      1.68     2.4      1.44
// 1.3    2          2.6      1.82                       2.6      1.69
// 1.4    2          2.8      2.1      2.8      2.24     2.8      1.96
// 1.5    2          3.0      2.4                        3.0      2.25
// 1.6    2          3.2      2.72     3.2      2.88     3.2      2.56
// 1.7    2          3.4      3.06                       3.4      2.89
// 1.8    2          3.6      3.42     3.6      3.6      3.6      3.24
// 1.9    2          3.8      3.8                        3.8      3.61
// 2.0    2          4.0      4.2      4.0      4.4      4.0      4.0
// 2.1    2          4.2      4.62                       4.2      4.41
// 2.2    2          4.4      5.06     4.4      5.28     4.4      4.84
// 2.3    2          4.6      5.52                       4.6      5.29
// 2.4    2          4.8      6.0      4.8      6.24     4.8      5.76
// 2.5    2          5.0      6.5                        5.0      6.25
// 2.6    2          5.2      7.02     5.2      7.28     5.2      6.76
// 2.7    2          5.4      7.56                       5.4      7.29
// 2.8    2          5.6      8.12     5.6      8.4      5.6      7.84
// 2.9    2          5.8      8.7                        5.8      8.41
// 3.0    2          6.0      9.3      6.0      9.6      6.0      9.0

Note vel10 / pos10 is the velocity / position at a framerate of 10 fps while vel5 / pos5 is the same at a framerate of 5 fps. The last column is calculated using the actual formula of constant accelerated movement p(t) = 0.5 * a * t² where “t” is the absolute time passed. As you can see the lower the framerate the greater the error after just 3 seconds. Also note the velocities are all correct since it grows linearly.

There is a trick to actually get the correct results for constant accelerated movements. However in physics simulations we even have changing accelerations like drag or spring forces which are not constant and those are impossible to “fix” with delta time. So FixedUpdate just provides common ground no matter the framerate because you always get the same call count and all physics calculations are always equally “off”, but at least consistent.