Search Unity

How exactly Time.fixedDeltaTime, Time.deltaTime are defined?

Discussion in 'Scripting' started by Dan2013, May 1, 2015.

  1. Dan2013

    Dan2013

    Joined:
    May 24, 2013
    Posts:
    200
    Hi,

    I am trying to understand those time-related concepts in depth.
    But I am confused with Time.fixedDeltaTime, and Time.deltaTime.

    Here below is a simplest script to output Time.fixedDeltaTime and Time.deltaTime.
    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. public class TimeLog : MonoBehaviour
    4. {
    5. void FixedUpdate()
    6. {
    7.   Debug.Log(string.Format("Fixed Delta Time: {0}", Time.fixedDeltaTime));
    8. }
    9. void Update()
    10. {
    11.   Debug.Log(string.Format("Delta Time: {0}", Time.deltaTime));
    12. }
    13. }
    14.  
    In Unity5's console window, what I got is:
    My first question is why Time.fixedDeltaTime has a larger value (0.02) compared to Time.deltaTime (around 0.01621689)?

    Based on my understanding based on the official docs
    http://docs.unity3d.com/Manual/ExecutionOrder.html
    http://docs.unity3d.com/ScriptReference/Time.html
    FixedUpdate() may be called multiple times between two calls of Update()?
    If that is true, then value of Time.deltaTime should be 1~N times larger of Time.fixedDeltaTime?

    My second question is how exactly Time.fixedDeltaTime, Time.deltaTime are defined?
    http://docs.unity3d.com/Manual/ExecutionOrder.html
    (Please see the picture of Script Lifecycle Flowchart)
    Based on my understanding, is this below a right event sequence?
    ... ...
    call FixedUpdate(),
    call Update(),
    Time.fixedDeltaTime passed,
    call FixedUpdate(),
    Time.fixedDeltaTime passed,
    call FixedUpdate(),
    Time.fixedDeltaTime passed,
    call FixedUpdate(),
    call Update(), // Thus, value of Time.deltaTime here is larger than 3*Time.fixedDeltaTime?
    Time.fixedDeltaTime passed,
    call FixedUpdate(),
    ... ...
    Is this event sequence above correct?
     
    Last edited: May 1, 2015
  2. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    deltaTime is the time it takes to execute one frame (specifically, the previous frame). By default the engine will attempt to do this as fast as possible. Your code affects how quickly the engine can process a single frame.

    fixedDeltaTime is affected by the settings of your physics simulation. It runs at a (more or less) fixed interval and is not affected by inefficiencies in your code. If your code makes the frame rate dip then fixedDeltaTime will be less than deltaTime and more than one physics simulation (FixedUpdate) will run within the span of a single frame. If you set the fidelity of your simulation to be lower or your code is very efficient then fixedDeltaTime will be greater than deltaTime.

    It should be noted that, because physics is simulated in a different thread, running 3 FixedUpdates in the span of a single Update does not increase deltaTime by a factor of 3.
     
  3. Dan2013

    Dan2013

    Joined:
    May 24, 2013
    Posts:
    200
    Hi, KelsoMRK

    Based on your description, is that possible Update() and FixedUpdate() runs concurrently in UnityEngine?

    But based on the Script Lifecycle Flowchart in this link:
    http://docs.unity3d.com/Manual/ExecutionOrder.html
    I think one Update() is called linearly after 1~N FixedUpdate() calls.
    That is why I give my "event sequence" as a guess. I may do some tests for it now.

    If you think my guess of "event sequence" is not correct.
    Would you give an "event sequence" to define how underlying things work?


     
  4. Dan2013

    Dan2013

    Joined:
    May 24, 2013
    Posts:
    200
    I runs a simple script to print an "event sequence" (actually, a call sequence).

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5. public class TimeLog : MonoBehaviour
    6. {
    7.     public LinkedList<string> calls;
    8.     public int totalNum;
    9.     public int maxNum;
    10.  
    11.     void countAndPrint(string toPrint)
    12.     {
    13.         if (totalNum == maxNum)
    14.         {
    15.             foreach (var call in calls)
    16.             {
    17.                 Debug.Log(call);
    18.             }
    19.             totalNum++;
    20.         }
    21.         else if (totalNum < maxNum)
    22.         {
    23.             calls.AddLast(toPrint);
    24.             totalNum++;
    25.         }
    26.         else
    27.         {
    28.             //totalNum > maxNum, does nothing
    29.         }      
    30.     }
    31.  
    32.     void Start()
    33.     {
    34.         calls = new LinkedList<string>();
    35.         totalNum = 0;
    36.         maxNum = 100;
    37.     }
    38.  
    39.     void FixedUpdate()
    40.     {
    41.         countAndPrint("FixedUpdate() is called");
    42.     }
    43.  
    44.     void Update()
    45.     {  
    46.         countAndPrint("Update() is called");
    47.     }
    48. }
    49.  
    I found there are few adjacent calls of Update().
    Printed call sequence is like:
    ... ...
    FixedUpdate() is called
    FixedUpdate() is called
    FixedUpdate() is called
    Update() is called
    FixedUpdate() is called
    Update() is called
    FixedUpdate() is called
    ... ...
    Update() is called
    Update() is called //few adjacent calls of Update()
    FixedUpdate() is called
    ... ...

    In addition, when I write MonoBehaviour script in C#, I assume all C# code is executed in one single thread where nothing is executed concurrently. I mean that writing Unity C# code is like writing some Node.js code, since I didn't find any multiple-threading, mutex lock, semaphore things from Unity official docs.

    This printed sequence of calls indicates that my previous guess is not completely correct.
    It also means that the Script Lifecycle Flowchart in this link below is not completely correct?
    http://docs.unity3d.com/Manual/ExecutionOrder.html

    I am still confusing about the underlying execution order...
     
  5. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    FixedUpdate runs off an accumulator of time. Something like this, internally:

    Code (csharp):
    1.  
    2. fixedUpdateAccumulator += timeSinceLastFrame;
    3.  
    4. while(fixedUpdateAccumulator >= fixedTimeStep)
    5. {
    6.      RunFixedUpdate();
    7.      fixedUpdateAccumulator -= fixedTimeStep;
    8. }
    9.  
    So it can run zero or multiple times per frame.

    Update is called once and only once per frame, after FixedUpdate.
     
    sanmn19 and Kiwasi like this.
  6. Dan2013

    Dan2013

    Joined:
    May 24, 2013
    Posts:
    200
    Thanks, KelsoMRK and GroZZIeR.
    I understand them now. I still think the Script Lifecycle Flowchart is not completely correct. It may contain an extra arrow to indicate that Update() part may happen without going through the FixedUpdate() part. But the doc explains that detail.
    Now, I realize that these two parts below
    FixedUpdate() with Time.fixedDeltaTime
    and
    Update() with Time.deltaTime
    are kind of independent to each other.

    That means if value of Time.fixedDeltaTime is high and Time.deltaTime is low, the physic simulation is very unrealistic. If I design some game depends some precise input and physic simulation, I should pay extra attentions to deal with this.

    For example, a Fighting Game should be able to precisely process external inputs and in game physic simulations at 60 FPS. If I design such a Fighting Game, what is the basic principle I should follow to make the input perfectly control game physic at 60 FPS?

    In addition, I also found Unity docs say that all input logic should be put in Update() (not in FixedUpdate())
    http://docs.unity3d.com/ScriptReference/Input.html
     
  7. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,539
    Well, yeah, the Script Lifecycle Flowchart isn't perfectly detailed, it's a generalized flowchart.

    The documentation still contains the detailed answer that you need though.

    If you want physics to calculate at 60fps, set the fixedDeltaTime (which is read-write) to 0.016667, that's roughly 60 times per second.



    And yes, Input should be used in Update. This is because 'Down' and 'Up' methods (Input.GetButtonDown, Input.GetButtonUp, Input.GetMouseDown, etc), are all dependent on what was happening the poll result the previous frame. Unity does this during the Update cycle.

    What will happen is that if FixedUpdate occurs multiple times between frames, these methods will return true that many times in a row. When the expected behaviour is for it to only happen once.

    If FixedUpdate happens 0 times that frame, and it's the frame that the button was pressed/released, FixedUpdate will never receive the signal.

    You COULD write your own methods that polled based on the FixedUpdate.
     
  8. Dan2013

    Dan2013

    Joined:
    May 24, 2013
    Posts:
    200
    @lordofduct
    I see. That is one possible way.
     
  9. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Wow. Some interesting misinformation in this thread.

    Update runs once per frame. Then the frame is rendered. Then FixedUpdate runs as many times as needed to catch the physics simulation up.

    Time.deltaTime changes depending on where you call it. In Update it represents the total time taken by the last frame. In FixeUpdate it represents the physics time step.

    This means FixedUpdate is great for physics like things that simulate a fixed time step. It sucks for things that need an actual fixed time step, like input, procedural sound, or fighting game physics.

    I you need an actual fixed time step, my suggestion is to create a new thread and use thread.sleep and timers and the like.

    Edit: fixed order of rendering call
     
    Last edited: May 4, 2015
    HappyDevilGames likes this.
  10. Dan2013

    Dan2013

    Joined:
    May 24, 2013
    Posts:
    200
    @ BoredMormon

    I am little bit confused about the "Execution Order" you describe above.
    You order is:
    Update() is called;
    one~several FixedUpdate() is called to "catch the physics simulation up"
    Then, frame is rendered.

    Your "Execution Order" seems quite inconsistent to the order shown in the Script Lifecycle Flowchart in this link:
    http://docs.unity3d.com/Manual/ExecutionOrder.html

    In the Flowchart above, the "Execution Order" seems to be:
    zero~several FixedUpdate() is called to do physic simulation;
    Update() is called;
    Then, frame is rendered.

    Am I still missing something important?
     
    Kiwasi likes this.
  11. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,539
    I'm pretty sure it's before as well.

    Though really, in the grand scheme of things, it technically doesn't matter. A fixedupdate may or may not come AFTER an update call as well (next frame). They're occurring all the time, and you just need to remember that they are used for 2 different things.
     
    Kiwasi likes this.
  12. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Nice catch, I'll edit my post to correct.

    Main point was, FixedUpdate doesn't run once every 0.02 seconds. It repeats itself as often as required to catch up. So with a poor frame rate and a quick physics loop, FixedUpdate might run 10 times in less then 0.005 of a second. Then it might not run again for another .1 of a second.

    The rest of the comments about the times to use it are still valid.
     
  13. roojerry

    roojerry

    Joined:
    Mar 18, 2013
    Posts:
    68
    ^This is wrong. You may need to go back and check the tutorials. FixedUpdate runs at a "fixed"/consistent time step. Update will vary based on the frame rate.
     
  14. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,539
    No, BoredMormon was right.

    FixedUpdate does not actually update every 0.02 seconds (or whatever you have the fixedDeltaTime set to). It will update when necessary, but will calculate all changes as if 0.02 seconds has passed, so that the physics calculates more deterministicly than if it were on a variable framerate like Update.
     
    arkano22 likes this.
  15. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    While technically correct (the best kind of correct!) when you're using real-world time, I think it is more useful to think of FixedUpdate running at a fixed interval. Time.time, for example, will reflect the "simulated" time at 0.02-second intervals (or whatever FDT is). As long as you're living in "game time", in other words, FixedUpdate executes in fixed intervals, and the Update-LateUpdate-Render cycle is effectively instant.
     
    Kiwasi and lordofduct like this.
  16. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,539
    I like the way StarManta puts it... it's fixed intervals in 'game time'.
     
    arkano22 and Kiwasi like this.
  17. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    I suggest you move beyond the tutorials. There is a lot of information in there aimed at beginners. Open up Unity and do a bench mark. You'll find I'm right.

    To do a benchmark set up an empty scene with a single GameObject. Create and attach a new script. In Update add some extraneous loops to slow your frame rate down to 5-10 FPS. Add a system timer so you can see the actual time things occur, (Time.time is fake to simulation time).

    Now add Debug.Logs to Update and FixedUpdate, with the time from your System.Timer. Report back on the results.
     
  18. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    True. Which is why it's great for simulated fixed time steps, like the physics engine. But it sucks for real time fixed time steps, like input.

    I believe I mentioned that in my earlier post. :)
     
    StarManta likes this.
  19. Dan2013

    Dan2013

    Joined:
    May 24, 2013
    Posts:
    200
    @ BoredMormon
    @ KelsoMRK
    @ StarManta
    @ GroZZleR
    @ lordofduct

    Thanks a lot for your guys' explanation. I got much better understanding about FixedUpdate() and Update().

    Now, I am really eager to find some reading materials about "Unity internal in depth".
    For example, I may want to find answers to these possible questions below.

    Question-1. What underlying C# native threads are running for different main components of Unity (e.g. physic simulation, rendering, GUI events)?
    I found official documentations do not contain enough related details in depth. I understand that Unity is a closed source engine. But knowing internal details is really helpful for developers to create better Unity programs.

    Question-2. How those underlying C# native threads are synchronized with each others?
    Actually, I see no mutex/semaphore things in official documentations. Thus, I assume whenever I add code into callbacks in monobehaviour, Unity architecture automatically does the mutex/semaphore things for me. Just like I am writing some single-threaded Node.js code.

    Question-3. I may want to know how strictly these rules below should be enforced?
    Rule-1. Call physic (Rigidbody-related) APIs in FixedUpdate() only.
    Rule-2. Call Input APIs in Update() only.
     
    Last edited: May 5, 2015
  20. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,539
    As far as I know... unity mostly uses the a single thread for most everything they give you access to operation of.

    Do note, that any threads they don't give you access to, there probably isn't a C# native thread that exists for it. Most of the unity engine guts are in the Unity engine core, which is all written in C++ and compiled for target platforms.

    Anyways,

    There is of course the main thread.

    Serialization/Deserialization has its own thread (or at least it runs at a time when unity won't let you access most of the unity engine). And you actually can operate on it if you implement the ISerializationCallbackReceiver interface... it's why they warn you to not really access unity specific stuff during said callbacks, you'll get exceptions/errors.

    They probably have threading for aspects of networking, and what not. Like WWW requests and the sort. But you don't really have access to operate on those threads. And therefore bet the threads don't exist from the Mono side of things.

    I'm betting they don't. I bet everything is synchronized on the engine side, unrelated to the Mono side, and the main thread hooks back to the Mono side.

    If the serialization really is a real separate Mono thread, I'm not sure exactly what they do, or what not... but in most cases, like instantiating a prefab, it happens right away, as there is no asynchronous instantiate methods.

    Also, I'm going to bet that when compiled for WebGL (unity 5), that no threading occurs at all. I say this because 1) webgl threading is annoying, and I don't take unity to really be jumping at doing that, 2) they explicitly state that you can't use .Net threads when compiling for WebGL.

    Yes, physics stuff aught to be in the FixedUpdate call, otherwise simulation won't look correct. Do recall, FixedUpdate is not its own thread or anything. It happens on the main thread, FixedUpdate and Update will never happen to be called parallel together. Threading is unrelated to this!

    As for the Input API... the only place that I personally find accessing it outside of FixedUpdate to not work is the persistent state methods.

    That being the 'Up' and 'Down' methods (GetButtonUp, GetMouseButtonDown, etc). This is because the current state is dependent on the state in the last frame. If you use FixedUpdate, you'll find GetButtonDown might return true multiple FixedUpdate calls in a row (happens a lot when framerate is below 50fps)... or it might not register the Down at all, if no FixedUpdate call occurs that frame cycle (happens a lot if your framerate is above 50fps).

    The methods that just returns the current state of the input, they tend to work just fine. GetAxis, GetButton, etc... these just tell you things like what the current stick axis is, or if the button is pressed at all. Even if these are updated on Update, it really doesn't impact reactions in FixedUpdate... because it's not dependent on the previous frame at all.
     
    Last edited: May 5, 2015
  21. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    Audio runs in it's own thread but that's largely meaningless to the end user of the API in that it doesn't affect how you write code.
     
  22. Dan2013

    Dan2013

    Joined:
    May 24, 2013
    Posts:
    200
    Last edited: May 5, 2015
  23. Dan2013

    Dan2013

    Joined:
    May 24, 2013
    Posts:
    200
    @ BoredMormon
    @ KelsoMRK
    @ StarManta
    @ GroZZleR
    @ lordofduct

    Guys, please confirm that if my current understanding is correct. :)

    Time.fixedDeltaTime in FixedUpdate() is some ideal (or expected) time interval that physic simulation process should follow. But in real scenarios, the whole system may be occasionally too busy (e.g. inefficient game logic code is used in Update()) to execute FixedUpdate() based on that ideal interval, Time.fixedDeltaTime.

    If that "too busy" scenario happens, the simulated physic process is delayed. Then, in that delayed situation, the physic simulation process should call FixedUpdate() many times during a short time (that has a much less measured value compared to Time.fixedDeltaTime) to do a "catching up" action to push the simulated physic process forward. This "catching up" action makes sure the simulated logic time in physic process synchronized with real world time.

    Thus, Time.fixedDeltaTime in FixedUpdate() is expected to be fixed;
    sometimes, its real measured values may vary.
     
  24. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    In real time: That's close to correct, except that you should expect "catching up" to be its default mode. If the CPU has extra time on its hands, it's not going to just hang around, nor is it going to pre-compute physics frames it doesn't need yet; it's just going to keep cranking out standard (Update/LateUpdate) frames. Only when Time.time crosses the next (fixedDeltaTime) threshold will it run FixedUpdate again, at which point it's already a fraction of a second "behind".

    In "game time": However, Time.fixedDeltaTime will ALWAYS return its set value, and in FixedUpdate, Time.time will always return the SIMULATED value, which will pretty much always be a direct multiple of your fixedDeltaTime. Try it yourself; create a script with Debug.Log's in Update, LateUpdate, and FixedUpdate that spit out Time.time. You'll see that the FixedUpdate outputs will all display their fixedDeltaTime as 0.02 and Time.time outputs will always be 0.02, 0.04, 0.06, 0.08, and so on.
     
  25. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,539
    @Dan2013
    You're WAY over thinking this...

    In 'game' terms, FixedUpdate happens at a fixed interval, in the game simulation.

    The 'Time' class reflects this simulated time.

    REAL time, outside of the simulation, can vary immensely. We don't want to be worried about some for loop taking 1ms vs 3ms screwing things up... so everything is on this simulated interval.

    Getting into this minutia is just going to confuse you. It's why unity's documentation doesn't really go into the specifics.

    FixedUpdate is for physics, and happens at a fixed interval (simulated time).
    Update is for everything else, and happens at a variable interval dependent on framerate.

    Time.deltaTime will return the deltaTime relative to the context it's called in... so if you call deltaTime in FixedUpdate, it returns the fixed deltaTime. Time.fixedDeltaTime is really just for setting the simulation speed.

    99.99% of the time, you don't really need to care that much about the rest of this stuff we're talking about.
     
    Kiwasi likes this.
  26. Dan2013

    Dan2013

    Joined:
    May 24, 2013
    Posts:
    200
    @ StarManta
    @ lordofduct

    So, Unity does not try to synchronize its simulated Time.time to some real world time at all.
    The Time.time is the only time that physic simulation process tries to follow.
    "catching up" action of physic simulation only happens if Unity detects that its simulated physic process is delayed compared to the simulated Time.time.
     
  27. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    This is true. The only time it ever matters is if you abuse FixedUpdate with non physics stuff.

    Time.time represents simulation time. If your timescale is 1, then this is equivalent to the real time at the start of the frame.
     
  28. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    Incorrect. I'm going to write a short story here, I call it A Day in the Life of the Unity Engine.

    Frame 1: It starts the game, it looks at the system clock, and marks that time as t=0, and it sets Time.time to 0. It runs through a frame (All the Awake, Start stuff because it's the first frame; then the standard FixedUpdate/Update/LateUpdate cycle as discussed above; I'm actually not sure if it calls FixedUpdate at Time.time=0 or not). When all that is finished, it packs up that frame and sends it off to the video card to get rendered. One frame down.

    Frame 2: Now, the engine goes back and looks at the system clock again. It finds that 0.062235423 seconds have passed since it looked at the clock last. (Note that it doesn't wait at all - as soon as it finishes calculating the previous frame, it moves on.) Well, better simulate that time! It sets Time.deltaTime to the Time.fixedDeltaTime and runs through the multiple FixedUpdates - one at Time.time being 0.2, one at 0.4, and one at 0.6 - and sees that it has now caught up. So now it sets Tiem.deltaTime to 0.062235423 and runs a single Update, LateUpdate, etc. It packs off the frame and sends it to the video card.

    While it's doing that, it also kindly asks the video card if the video card has finished rendering frame 1 yet, and if not, it waits at this point - no sense spending CPU time on frames faster than the GPU can render them.

    (Note that, while Time.time is based on the system clock, it is based on what the system clock was when the frame started to be calculated.)

    Frame 3: Again the engine looks at the clock. Since the last time it checked, another 0.0133 seconds have passed, probably faster this time because it didn't have all that initialization to do. It adds this to its previous "time elapsed" and sees that the resulting Time.time is 0.075535423. The next physics frame isn't needed until 0.08, so it skips that (and the FixedUpdate calls), and sets Time.deltaTime to 0.0133, Time.time to 0.075535423, and goes straight to Update. Finishes the frame, packs it off to the video card.

    Does this process make sense?
     
  29. Dan2013

    Dan2013

    Joined:
    May 24, 2013
    Posts:
    200
    @ StarManta
    Really make sense. Thanks a lot!

    One more thing about implementing physic simulation.

    When doing the catching up physic simulation (e.g. at time of 0.2, 0.4, 0.6 between Frame 2 and Frame 3), Unity may also asks helps from video card if it supports PhysX. If video card does some physic simulation work, it runs some physic simulation subsystem concurrently that is independent to its rendering subsystem.
     
  30. 18fanna

    18fanna

    Joined:
    Sep 21, 2016
    Posts:
    1
    " It sets Time.deltaTime to the Time.fixedDeltaTime and runs through the multiple FixedUpdates - one at Time.time being 0.2, one at 0.4, and one at 0.6 - and sees that it has now caught up." It looks like the Game runs FixedUpdates many times in one short duration. So the Physics Detection is not reliable.... Is this right?


    Ok.. I get it.. It is hard to understand the simulation time or discrete time..
     
    Last edited: Sep 21, 2016
  31. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    What do you mean by physics detection? Collision detection will run once per FixedUpdate, and so is reliable. Input detection runs once per Update, so should not be relied on in FixedUpdate.