Skip to content
Menu
13Pixels Blog 13Pixels Blog
  • Hi, it’s FlaSh.G!
13Pixels Blog 13Pixels Blog

What exactly is FixedUpdate?

Posted on 2019-03-272022-08-17 by FlaSh.G

When the first video games were created, computers were simple – at least compared to modern machines. A properly written program running on a C64 or a Gameboy could rely on a rather consistent computation power. And a game would have its calculations designed in a way that worked for the resulting framerate.

Today, computers, consoles and even phones are powerful machines that have the capability to compute many things at once. PCs usually have dozens of programs running in addition to background tasks and a programmer cannot make any assumptions about the actual computation power available to the program.

As a result, framerates cannot be predicted, and games have to be able to run properly with 30, 60 or 144 frames per second (“fps”) – and anything inbetween. Games ported from consoles where this isn’t an issue quite as much stand out every now and then for having varied player experience depending on computation power.

This article sheds some light on FixedUpdate, which is a concept that allows you to build framerate-independent game simulation. It’s beneficial to fully understand what it is… and what it isn’t.

About Time.deltaTime

Probably the most basic event Unity beginners get to know is “Update“. Update is called once every frame on every active component in the scene. It can be used for pretty much anything in a game. Moving or rotating an object, changing a light color, noticing a button being pressed and reacting accordingly… everything.

If we were to move an object by one meter in Update, it would move one meter with every frame the game renders. If we had 30 frames per second, we’d move 30 meters per second. With 60 fps, we’d move 60 meters in the same time. This is obviously unacceptable, as the gameplay drastically changes with a value neither the programmer nor the player usually has any control over.

When someone first gets into game development with Unity, one of the first things they learn is that there is this thing called “Time.deltaTime” telling them how much time it took the machine to compute the most recent picture on the display. This includes simulating the game world as well as rendering the image.

Multiplying a value with Time.deltaTime basically means adding a “per second” to it. If we have 30 fps, Time.deltaTime‘s value is 1/30, and moving 1/30m 30 times means moving 1m within one second. With twice the fps, Time.deltaTime is half as high, so we move twice as often, but each time we move only half as far. This means that after a second, we always have moved one meter.

However, this concept is limited to linear processes. A continuous motion, be it movement, rotation or anything else, works fine with this approach. But if we add another dimension, like an object being thrown into the air and gravity pulling it down, this doesn’t work anymore.

To visualize this, consider this ball jumping forward.

A ball launching into the air.
Left: With a high framerate
Right: With a low framerate

With a high framerate, the ball will update its direction very often. With a low framerate, gravity can only be applied a few times during the flight. And even if Time.deltaTime is used for both the movement and the applied gravity, the frequency of updates to a non-linear process matters. Time.deltaTime cannot solve this problem.

FixedUpdate to the rescue

Sooner or later, one stumbles upon the FixedUpdate event. Unity’s scripting reference says:

0.02 seconds (50 calls per second) is the default time between calls.

Unity Scripting Reference about FixedUpdate

And this can be dangerously misleading. It might sound as if Unity manages to magically enforce a call every 0.02 Seconds (or whatever the fixed timestep is set to), but this is not the case. The scripting reference uses this terminology because it’s okay to assume this would be how it works… for now.

In reality, FixedUpdate works like this.

Unity has a stopwatch running in the background that measures time as it passes. Before every Update, that stopwatch is checked. If the passed time is higher than the fixed timestep (e.g. 0.02 seconds), a FixedUpdate is triggered, and the stopwatch’s timer is reduced be the fixed timestep.

In other words: Unity checks the time before every Update, and if it notices that it actually should have triggered a FixedUpdate by now, it does so. This goes even further as Unity might notice that multiple FixedUpdates would have already been in order. In this case, it triggers multiple FixedUpdates in a row without doing anything else inbetween – like redrawing the game or calling Update.

Through this, we get a cycle that will try to run every 0.02 seconds by catching up to the amount of FixedUpdates we should have had by now.

In addition to this, within FixedUpdate, Time.deltaTime switches to return nothing but the fixed timestep value. So if we handle FixedUpdate just like we handle Update, we can run something with a seemingly constant framerate and let our objects behave like it was real.

Thus, FixedUpdate should be used for all non-linear processes that are relevant to gameplay, in order to ensure that every player has the same gameplay regardless of their hardware power.

Issues with FixedUpdate

What may seem like a reason to never use Update again comes with some drawbacks… which we can handle.

First off, the game still draws itself onto the player’s screen with every Update. If there’s multiple Updates between two FixedUpdates because the framerate is high, the player will be able to see that an object didn’t get (fixed)updated between two frames. This means a visible stutter effect.

This issue can be solved with a script I wrote some time ago and used and maintained ever since: FixedUpdateInterpolation. You can add it to your project and add it to any GameObject that is moved or rotated in FixedUpdate. What it does is to identify where between two FixedUpdates the time is in Update, and to interpolate between the two. An object moving in FixedUpdate will move between its previous and its current position with every rendered frame. Rigidbody and Rigidbody2D components offer the same functionality with their Interpolate property.

Secondly, input happens each Update. And whether there’s multiple Updates between two FixedUpdates due to a high framerate, or multiple FixedUpdates between two Updates due to low fps, checking input within FixedUpdate will lead to lost button presses or a button press counting multiple times.

This problem can be solved by adding some additional code for buffering button presses:

private bool jump;

private void Update()
{
  if (Input.GetButtonDown("Jump"))
  {
    jump = true;
  }
}

private void FixedUpdate()
{
  if (jump)
  {
    Jump();
    jump = false;
  }
}

Note that this is only necessary for button presses and releases. When you ask whether a button has just been pressed, you will only get back a “yes” in the first Update after the button press. If there is another Update after that, the button will not count as “freshly pressed” anymore, and if your FixedUpdate call comes after that, you won’t even notice that a button was pressed inbetween.

If a button is held over a time, or if you check a joystick’s analog output, this isn’t needed, as the state of that input doesn’t change after an update.

A small update: The InputSystem package has a built-in solution for polling button presses in FixedUpdate, so using that is a good idea.

Implementing your own FixedUpdate

To get a better understanding, or even for actual uses in your project, you can rather easily create your own FixedUpdate cycle with code like this:

public float fixedTimestep = 0.02f;
private float timeSinceLastFixedUpdate = 0f;

private void Update()
{
  timeSinceLastFixedUpdate += Time.deltaTime;

  // Call MyFixedUpdate as often as needed to catch up
  while (timeSinceLastFixedUpdate >= fixedTimestep)
  {
    MyFixedUpdate();
    timeSinceLastFixedUpdate -= fixedTimestep;
  }
}

private void MyFixedUpdate()
{
  // For example:
  transform.Translate(Vector3.forward * fixedTimestep);
}

Note how “fixedTimestep” is used instead of Time.deltaTime in “MyFixedUpdate“.

Conclusion

FixedUpdate allows you to create games that offer the same gameplay experience for any reasonable framerate. This is not possible with Update and Time.deltaTime – unless all your gameplay processes are linear. And they never are.

But it’s important to understand how FixedUpdate really works and that certain aspects of it can lead to undesirable effects or hard-to-reproduce bugs. Learning how to work with FixedUpdate is an essential part of making a good game, so make sure you know it in and out!

A small update on this article…

After having stumbled upon this thread in the Unity forums, it sounded like there’s advice given to not use FixedUpdate for anything but physics. The first post contains what I would call at least very badly worded, if not just incorrect information, and the second post agrees, although the argument of that user is a different one later on.

Long story short: FixedUpdate, as described in this article, is a concept. When I recommend to use it for everything deterministic, that doesn’t mean you have to use Unity’s builtin FixedUpdate method. Just like a changing framerate can change the game experience, so can changing the fixed timestep at some point in development. And if you do different things in a “FixedUpdate-like structure”, it might be a good idea to have multiple fixed timesteps. Using only the builtin FixedUpdate doesn’t directly allow you to do that. In the long run, with sufficient project complexity (!), it is a useful idea to roll your own FixedUpdate (like described above) and keep only the physics-related code in Unity’s builtin FixedUpdate event.

Recent Posts

  • Unity and the mysterious singleton
  • Communicating Objects
  • Reference Semantics for Beginners
  • How Unity destroys objects
  • Unity Game Initialization

13Pixels in the Unity Asset Store

Soda - ScriptableObject Dependency Architecture

Check out Soda and more assets in the Unity Asset Store!

Discuss with other Devs

Join the 13Pixels Slack Workspace for discussions and updates.

©2025 13Pixels Blog | Powered by WordPress & Superb Themes