Search code examples
unity-game-engine

How Update really works in Unity?


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.


Solution

  • So the diagram is kinda misleading. Your understanding is correct, 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.