1

I have a sample scene with only one object with script on it. Even without camera. The script is next:

using UnityEngine;

public class UpdateTest : MonoBehaviour
{
    private void Update()
    {
        Debug.Log("Update");
    }
    
    private void FixedUpdate()
    {
        Debug.Log("FixedUpdate");
    }
}

In the console I can observe next output after ~5 seconds: enter image description here

In general, I have two questions about this.

1) How does Unity determine when `Update` should be called?

Unity docs says:

Update is called once per frame. It is the main workhorse function for frame updates.

Target fps is set to 60 in my project settings. But Update is called ~1000 times per second.

2) How `Update` could be called more times than `FixedUpdate`

There is a block-scheme of Unity loop. There is a simplification of it regarding FixedUpdate and Update:

enter image description here

According to it, FixedUpdate could be called several times for one Update, but not vice versa.

Previously I thought, that FixedUpdate is some sort of a "tick" of an engine. But now, I'm confused about all of this.

Nikolai
  • 656
  • 6
  • 19
  • Does this answer your question? [what is the difference between Update & FixedUpdate in Unity?](https://stackoverflow.com/questions/34447682/what-is-the-difference-between-update-fixedupdate-in-unity) – BugFinder May 18 '23 at 18:29
  • 1
    I'm afraid this issue cannot be reproduced. Tested in an empty scene that only has a gameobject with the script. "FixedUpdate" and "Update" are printed in a 10:12 ratio, which is bang on for the timing of 0.02 (default timestep) ańd 0.01667 seconds (60 fps). – Voidsay May 18 '23 at 18:33
  • `FixedUpdate` doesn't need to be called before `Update` does. It's not shown in the flowchart at all (which is a bit confusing), but I'm pretty sure that if not enough time has gone by for a fixed timestep, it will just skip calling `FixedUpdate`. – joll05 May 18 '23 at 18:42
  • The block scheme is a lie. `Update` and `FixedUpdate` work in "parallel" and in fact `FixedUpdate` is slower when you use the default values. For most intends and purposes `FixedUpdate` can be called a "tick" that makes the engine execute code every x seconds, but it breaks down a bit when you manage to write something that takes longer to calculate. The computer can take as much time as needed to finish all fixed updates (lets say a minute), but for the purpose of calculating physics the timer only advanced a fraction of a second. – Voidsay May 18 '23 at 18:42
  • @Voidsay The second part of my question is still makes sense for 10/12 rate of FixedUpdate and Update. – Nikolai May 18 '23 at 19:23
  • Some comments seem mistaken, the diagram is accurate. The phases update/fixed update never run in parallel. It's all sequential, single threaded. The `FixedUpdate` phase is called before `Update` every frame. Its just the Fixed updates will be called `0`, `1` or *many* times, depending on the framerate and how many fixed updates are needed to give a framerate independant rate. This doesn't mean that each FixedUpdate will be equidistant in real time, just that a frame rate drop will be accounted for *on average* over a couple of frames such that the corect number of FixedUpdates will be called. – Jay May 18 '23 at 20:48

2 Answers2

2

So the diagram is correct, as is your understanding, except for one part:

The FixedUpdate step can enter that loop on the diagram

  1. It can call FixedUpdate just one time
  2. It can call FixedUpdate more than once,
  3. 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 60fps.

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/60s 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/30s 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 120fps, then you don't want extra FixedUpdate calls. So, unity will reach the FixedUpdate phase, see that its been only 1/120s 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/60s since last FixedUpdate and will call the function once. Effectively making FixedUpdate run only every second frame.

It's important to remember that

  1. Unity is single threaded in this process, nothing magic is happening and nothing is happening truly in parallel.
  2. 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.

Jay
  • 2,553
  • 3
  • 17
  • 37
0

Update will be evaluate each frame. Frames are time independent, so if you have a heavy calculations on that frame could be take more time to process that frame.

FixedUpdate is time dependent and you can set the time for each cycle on Project Settings/Time/Fixed TimeStep.

The scheme is simple, first method to be evaluate is FixedUpdate like you see on your console log the first log is FixedUpdate, then will evaluate Update, if still is not time to evaluate FixedUpdate this will be skip and will evaluate Updated method. In terms of both need to be execute at same time fixed update will take priority over update.

In resume that is the order of execution, not mean that fixedUpdate will be evaluate always that Update will be evaluate, just will skip fixedUpdate and evaluate the update

To limit the application FrameRate you need to set the application framerate with using the class Application, if you set the value to -1 will run at maximum fps that the system can run.

Example:

private void Awake()
{
    Application.targetFrameRate = 60;
}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Mario
  • 601
  • 3
  • 7