1
\$\begingroup\$

I was thinking about games on low end machines or phones where the CPU would be limited. If I were to move all of my game logic into FixedUpdate() can I assume that it will always be called with the same time delta? Or would it still be worth adding code to make it take the actual time delta into account?

\$\endgroup\$
  • 1
    \$\begingroup\$ It's worth noting that FixedUpdate is "fixed" with regard to the simulation time represented by each step, not with regard to realtime. There's a common misconception that FixedUpdate is called on a regular timer, when in fact it runs at the beginning of each frame and loops back-to-back some number of times to catch up to the current game time. So, reliability with regard to simulation consistency, and reliability with regard to realtime event sequence are distinct questions. If I understand correctly, you're asking about the former - how much game time is simulated in each fixed step, yes? \$\endgroup\$ – DMGregory Nov 11 '16 at 21:00
4
\$\begingroup\$

I've done some tests simulating low framerate conditions, and empirically confirmed that the deltaTime value for each FixedUpdate step does indeed stay consistent.

For example, using the default Fixed TimeStep of 0.02 (50 Hz) and Maximum Allowed Timestep of 0.3333333 (as set in Edit -> Project Settings -> Time)...

  • At 60 fps we get 0-1 physics & FixedUpdate steps per frame
  • At 30 fps we get 1-2 physics & FixedUpdate steps per frame
  • At 15 fps we get 3-4 physics & FixedUpdate steps per frame
  • At 3 fps we get 16-17 physics & FixedUpdate steps per frame, and we hit the max allowed timestep
  • For any lower framerate, Unity clamps the real time elapsed to 0.33333, so we continue to get just 17 physics & FixedUpdate steps per frame

Throughout the whole spectrum, every call to FixedUpdate gets the same deltaTime value of 0.02. The variability in timing is handled solely by running more or fewer iterations, not by scaling the deltaTime value - exactly as we should expect for a "fixed" timestep.

As shown above, when the framerate is extremely low, Unity will limit the amount of time by which it advances the game simulation, capping at 17 FixedUpdate iterations with the default settings.

So, if you want to know that the game time represented by each FixedUpdate iteration remains the same, the answer is yes (as long as you don't assign a new value to Time.fixedDeltaTime directly)

If you want to know whether the realtime interval represented by each FixedUpdate iteration remains the same, the answer is no - at extremely low framerates, Unity will cap the number of FixedUpdate steps, allowing game time to run slower than realtime. Also, as noted in a comment above, all the physics steps and FixedUpdates for a given frame occur back-to-back at the beginning of the frame's execution, not evenly distributed in realtime like a metronome.


In doing this test, I learned some interesting things about how Unity handles Time.timeScale:

  • Slowing/speeding game time with timeScale does not modify the deltaTime of each call to FixedUpdate - you'll just get fewer or more steps in a given frame, again as we should expect from a fixed timestep.

    If you want to increase physics time resolution when running in slowmo, modify Time.fixedDeltaTime when going in & out of the time warp.

  • The enforcement of Maximum Allowed Timestep occurs before multiplying by timeScale. So if I use Time.timeScale = 0.5f to slow the game by half, the maximum deltaTime I'll see in Update will be 0.16666666 instead of 0.33333333

\$\endgroup\$
  • \$\begingroup\$ Oh wow. I thought that the update was simply called after the physics step but this appears to show that it is much more involved than that! Thanks for the testing. How did you slow down the frame rate in the tests? just some arbitrary calculation I assume (while(not X amount of time has passed) or something like that)? \$\endgroup\$ – user3797758 Nov 12 '16 at 1:22
  • \$\begingroup\$ I used System.Threading.Thread.Sleep in an Update method to increase the time the main thread takes to complete each frame. :) \$\endgroup\$ – DMGregory Nov 12 '16 at 1:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.