Search Unity

The truth about FixedUpdate()

Discussion in 'Scripting' started by gregzo, Mar 1, 2014.

  1. RElam

    RElam

    Joined:
    Nov 16, 2009
    Posts:
    375
    This is a very good question/point. I target 60fps, but run physics at 30. There are in fact many functions that do not need to run every frame... in my case I run minimap updates, AI updates, and several other things in frames where physics did not run, and works quite well. IMO, the big question is are you targeting 60FPS, or are you locked at it. If you're on a stable target platform, like consoles, then locking physics to 60 isn't that bad, but on a variable target like PC, your per fixed update CPU cost becomes far more important, and it's wise to make sure your physics requirements are actually your minimum requirements, not your average or desired target hardware, since physics does not scale. For the vast majority of game types, players can't even tell the difference between physics run at 60 vs 30, so running physics at 30 is helpful, but if your physics starts getting heavy yet you are still running at 60FPS (say, your physics/FixedUpdate gets close to 4ms), you will want to run other things in the non-physics frames or you're creating a slightly inconsistent framerate, which may not be a net positive for user experience.
     
  2. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    I think some mild abuse of max timestep is needed I guess.
     
    OZAV likes this.
  3. OZAV

    OZAV

    Joined:
    Aug 9, 2013
    Posts:
    299
    I agree with hippocoder :)
    Also, in our many practices, void FixedUpdate () { is one of my favorite moves,
    and always will be (plus - it's physics) ... I often put there many (fast execution)
    stuff, as well, so the code balance gets better that way, overall the project (s).
    *** It's all (like always) - not what you use, and where, but - HOW do you use it,
    and how-often-where... Using it around really gets down some nasty spikes,
    from Profiler. And is my experience i'd like to report, in the defense of FixedUpdate, so
    why accuse it of anything bad, other than other "update" guys in Unity do ?
    So, shortly - Fixed Update () ? dunno about your reasons, but - escaping into it,
    often, with some (say) weapons shooting codes does the job better than Update,
    if you're not putting much other stuff into it. Your Zen is the balance, your nose will
    tell you how much (it's like a fine seasoning, in cooking; FixedUpdate () { :) :) :)
    So, there is an Unity Club, and FixedUpdate Club - and I simply LOVE IT !
     
    Last edited: Nov 19, 2016
  4. Mazer83

    Mazer83

    Joined:
    Mar 14, 2016
    Posts:
    19
    Why not use a sort of "dead reckoning" method? In Update() you do all of your heavy stuff involving lots of vector normalizations, getting the angles between vectors, figuring out what to do next, who to shoot at, etc.. and you store simple instructions like: "Move 3 meters this way, turn 20 degrees that way", and so on. Then, in FixedUpdate, you simply go through the instructions.
     
  5. Jamate

    Jamate

    Joined:
    Nov 14, 2016
    Posts:
    6
    Hello, I am not a professional programmer, however if everything is done in the same thread, why:

    Code (csharp):
    1.  
    2. bool insideFixedUpdate = false;
    3.  
    4. FixedUpdate() {
    5.     insideFixedUpdate = true;
    6.  
    7.     ...
    8.  
    9.     insideFixedUpdate = false;
    10. }
    11.  
    12. Update() {
    13.     if (insideFixedUpdate == true)
    14.         Debug.Log("... more threads ...");
    15. {
    16.  
    the result is:
    ... more threads ... ?

    Thanks,
    MJ
    --
     
  6. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,338
    That should not be happening at all. Do you have the entire example script? My guess would be that there's a return somewhere in "..."
     
    Kiwasi likes this.
  7. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Because you've gone and done something wrong. That's not the result you get with that code in Unity.
     
    Bunny83 likes this.
  8. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Just a heads up for the new 2017 betas of Unity:

    The truth about fixed update is you no longer need it. For 2D you don't even need OnCollision either with the ability to get contacts.

    As of 2017, people can call physics simulate manually and it's OK to use within Update (time sliced or otherwise - time sliced would be the same as existing fixed update with finer-grained control).

    So I advocate most people having trouble with the old way move to the new. This could be people who need the control exactly when it happens, or people who need to simulate more than once, and especially people who don't use physics that heavily - can simplify things a lot with input and so on just running it same frequency as your normal code.
     
  9. Dave-Carlile

    Dave-Carlile

    Joined:
    Sep 16, 2012
    Posts:
    967
    Is this documented somewhere?
     
  10. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Check the beta forums and have at it :)
    There will be unfortunately minimal documentation until launch but launch is not too far off now, so it is just buried in the release notes somewhere for now - and maybe will be in the beta docs.
     
    Dave-Carlile likes this.
  11. Dave-Carlile

    Dave-Carlile

    Joined:
    Sep 16, 2012
    Posts:
    967
    Oh, when you say "2017" you mean the next Unity version, not the year :)
     
    hippocoder likes this.
  12. Jamate

    Jamate

    Joined:
    Nov 14, 2016
    Posts:
    6
    I attached the script.
     

    Attached Files:

    • main.cs
      File size:
      3.3 KB
      Views:
      998
  13. Jamate

    Jamate

    Joined:
    Nov 14, 2016
    Posts:
    6
    The problem will arise after [space] is pressed, which calls ResetPosition() method.
     
  14. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,338
    Your code will only print "... more threads ..." if it gets an exception in the middle of FixedUpdate. That will happen if one of your markers gets deleted.

    If you need help figuring it out, you should probably make a new thread for that.
     
  15. ZJP

    ZJP

    Joined:
    Jan 22, 2010
    Posts:
    2,649
    Marrt and Dave-Carlile like this.
  16. Jamate

    Jamate

    Joined:
    Nov 14, 2016
    Posts:
    6
    Thank you very much. I noticed the exception, however I don't know why it is throwns. Is my use of the prefab wrong? The only I want is to create a new instance (and at first delete the old one) of prefab when I press [space].
     
  17. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,338
    Which line exactly is throwing the exception?

    As I said, it's (probably) a MissingReferenceException due to you trying to do something with a GameObject that's been destroyed, but it's hard to tell exactly which one.
     
  18. Marrt

    Marrt

    Joined:
    Feb 7, 2012
    Posts:
    613
    A tad more Control over Physics would be refreshing! Last month i completely bloated the TickManager to get more control over when things happen, so i added these two features:

    • AddPrePhysicsUpdateCoroutine( IEnumerator coroutine ) //yield coroutine by "yield return null;"
    When you toss a Coroutine into this function, the coroutine will be called every fixedFrame BEFORE the internal Physics Update. I needed this because "yield return new WaitForFixedUpdate();" will continue the Coroutine AFTER the internal Update and AFTER the Collision stuff, so you are always late.
    upload_2017-5-25_10-38-43.png

    • FirstTick1 & 2
    If you want to fetch Input before the Physics Update, you could only ever do so by Fetching it in FixedUpdate(). But because FixedUpdate() does not reliably happen every frame, you will miss KeyUp|Down events. My events "FirstTick1" and "FirstTick2" will reliably be called every frame and before the Internal physics Update - should one happen this frame. Therefore you can use it for InputFetching

    Why do i even need this? Faster response times:
    - I create Attack-Hitboxes based on Input
    - when the player presses "Slash" i want the Game to create the Slash-Hitbox ASAP
    - Previously:
    The player pressed Slash, Update() would fetch the Input and create the Hitbox which will cause its collisions earliest in the frame n+1 after its internal physics-Update. Sometimes even later, n+2, n+3, imagine this frame had a physics-Update (which we missed by fetching in Update) and next frame there is none. The Hitbox collision will create a hit earliest in n+2.

    - Now:
    I press "Slash", the Input is fetched by the function i subscribed to firstTick1 and the AttackHitbox will be created before the CURRENT internal-physics-routine and collision-handling -should one happen this frame

    "Nice Marrt, this gives you about ~30ms faster response times average, who cares"
    - I'll gladly take 30ms anytime if they come at virtually no cost. Also if you Tinker with this stuff, you get a way better idea of the chronological order your stuff happens, helps heaps when debugging

    Here is the script:
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine;
    3. using System;
    4. using System.Collections;
    5. using System.Collections.Generic;    //List of IEnumerators
    6.  
    7. //http://answers.unity3d.com/questions/59876/how-to-achieve-a-latefixedupdate-effect.html
    8.  
    9. /// <summary>
    10. /// TickManager for better control of when things happen, put this on a persistent GameObject in your startscene
    11. ///
    12. /// usage: subscribe to event within OnDisable and OnEnable
    13. ///        void OnEnable(){  
    14. ///            TickManager.FirstTick1    += MyInputFetcher;
    15. ///            TickManager.FixedTick1    += MyFixedUpdate;
    16. ///            TickManager.FixedTick2    += MyLateFixedUpdate;
    17. ///            TickManager.Tick1        += MyUpdate;
    18. ///        }
    19. ///        void OnDisable(){
    20. ///            TickManager.FirstTick1    -= MyInputFetcher;
    21. ///            TickManager.FixedTick1    -= MyFixedUpdate;
    22. ///            TickManager.FixedTick2    -= MyLateFixedUpdate;
    23. ///            TickManager.Tick1        -= MyUpdate;
    24. ///        }
    25. ///        private void MyInputFetcher(){
    26. ///            //don't do physics stuff in here,
    27. ///            //only prepare stuff that the next physics loop picks up,
    28. ///            //like setting jump flag that resets after it is used in the actual physics step or
    29. ///            //updating a moveInputVector that is used to change velocity
    30. ///            //-this is how you should do it anyway, even without this tickmanager
    31. ///        }
    32. ///        private void MyFixedUpdate(){ /*your previous FixedUpdate() code here*/ }
    33. ///      
    34. /// Order:
    35. ///         1 firstTick1        // once per frame before the fixed ticks, can fetch Input before Fixed Update, happens even if no fixed Update happened this frame
    36. ///         2 firstTick2
    37. ///        
    38. ///        Physics{    //may happen multiple times per game-loop or not at all
    39. ///         3 fixedTick1;        // use this to replace FixedUpdate()
    40. ///         4 fixedTick2;        // use this to replace FixedUpdate()
    41. ///         5 every coroutine subscribed by AddPrePhysicsUpdateCoroutine()
    42. ///         - INTERNAL PHYSICS UPDATE, this is where stuff is actually moved
    43. ///         - OnTriggerXXX
    44. ///         - OnCollisonXXX
    45. ///         6 fixedCoTick1
    46. ///         7 fixedCoTick2
    47. ///        }
    48. ///      
    49. ///         8 tick1            // use this to replace Update() by subscribing a Custom function to tick1()
    50. ///         9 tick2
    51. ///        10 coTick1
    52. ///        12 coTick2
    53. ///        13 lateTick1
    54. ///        14 lateTick2
    55. /// </summary>
    56. public class TickManager : MonoBehaviour {
    57.    
    58.     private    bool firstTickSubmitted = false;
    59.     public static event Action FirstTick1;        // always the first event per frame, can be used to fetch input before Fixed Update in order to use it for physics without delay
    60.     public static event Action FirstTick2;        // second tick for first tick, can be used if inputs at firstTick1 create changes that must still be dealt with in other scripts before physics
    61.  
    62.     public static event Action FixedTick1;        // use this to replace FixedUpdate()
    63.     public static event Action FixedTick2;        // use this to replace FixedUpdate()
    64.     //INTERNAL PHYSICS UPDATE, this is where stuff is actually moved, check below UpdateBEFOREPhysicsCoroutine to see how implement something that runs in coroutine before physics update unlike yield return new WaitForFixedUpdate()
    65.     //OnTriggerXXX
    66.     //OnCollisonXXX
    67.     public static event Action FixedCoTick1;    // yield return new WaitForFixedUpdate();
    68.     public static event Action FixedCoTick2;    // yield return new WaitForFixedUpdate();
    69.    
    70.     public static event Action Tick1;            // use this to replace Update()
    71.     public static event Action Tick2;
    72.     public static event Action CoTick1;
    73.     public static event Action CoTick2;
    74.     public static event Action LateTick1;
    75.     public static event Action LateTick2;
    76.  
    77.    
    78.     void Awake () {
    79.         StartCoroutine(CoroutineTick());
    80.         StartCoroutine(FixedCoTick());
    81.        
    82.         //Profiling test for AddPrePhysicsUpdateCoroutine
    83.         //for(int i = 0; i<100000; i++) {    AddPrePhysicsUpdateCoroutine( UpdateBEFOREPhysicsCoroutine() );    }
    84.     }
    85.  
    86.  
    87.     private static List<IEnumerator>    preInternalPhysicsRoutines    = new List<IEnumerator>();
    88.     private static List<IEnumerator>    preInternalRemovalMarker    = new List<IEnumerator>();
    89.    
    90.     /// <summary>
    91.     /// Add your IEnumerator here, yield by 'yield return null;'
    92.     /// save a reference to your coroutine before adding, never call StartCoroutine on it:
    93.     ///      
    94.     ///        Start:
    95.     ///        myCoroutineReference = MyCoroutine( myVar1, myVar2 );
    96.     ///        AddPrePhysicsUpdateCoroutine( myCoroutineReference );
    97.     ///
    98.     ///        Removal:
    99.     ///        After it has been finished it is automatically removed, you can also manually remove it
    100.     ///        RemovePrePhysicsUpdateCoroutine( myCoroutineReference );
    101.     ///        (is there a memory buildup problem i might not aware of?, do i have to end the IEnumertor explicitely somehow, profiler seems fine)
    102.     ///
    103.     /// </summary>
    104.     public    static    void AddPrePhysicsUpdateCoroutine    ( IEnumerator coroutine )    {    preInternalPhysicsRoutines.Add        (coroutine);    }
    105.     public    static    void RemovePrePhysicsUpdateCoroutine( IEnumerator coroutine )    {    preInternalPhysicsRoutines.Remove    (coroutine);    }
    106.  
    107.     //How to get a Coroutine to run BEFORE INTERNAL PHYSICS UPDATE?
    108.     IEnumerator UpdateBEFOREPhysicsCoroutine() {
    109.         //TEST: dont start this via StartCoroutine, use AddPrePhysicsUpdateCoroutine( UpdateBEFOREPhysicsCoroutine() );
    110.         int i = 0;
    111.         for(;;) {
    112.             i++;
    113.             if(i == 100) { break; }
    114.             yield return null;
    115.         }
    116.     }
    117.     /// <summary>For Debuggung Print the amount of subscriptions that are hooked to the events</summary>
    118.     public string PrintSubCounts(){
    119.         string s = "";
    120.        
    121.         s +=    "firstTick\t\t"    +"["+    (FirstTick1        ==null?"000":FirstTick1.    GetInvocationList().Length.ToString("D3"))+"]\n";
    122.         s +=    "firstTick\t\t"    +"["+    (FirstTick2        ==null?"000":FirstTick2.    GetInvocationList().Length.ToString("D3"))+"]\n";
    123.         s +=    "fixedTick1\t\t"+"["+    (FixedTick1        ==null?"000":FixedTick1.    GetInvocationList().Length.ToString("D3"))+"]\n";
    124.         s +=    "fixedTick2\t\t"+"["+    (FixedTick2        ==null?"000":FixedTick2.    GetInvocationList().Length.ToString("D3"))+"]\n";
    125.         s +=    "fixedCoTick1\t"+"["+    (FixedCoTick1    ==null?"000":FixedCoTick1.    GetInvocationList().Length.ToString("D3"))+"]\n";
    126.         s +=    "fixedCoTick2\t"+"["+    (FixedCoTick2    ==null?"000":FixedCoTick2.    GetInvocationList().Length.ToString("D3"))+"]\n";
    127.         s +=    "tick1\t\t"        +"["+    (Tick1            ==null?"000":Tick1.            GetInvocationList().Length.ToString("D3"))+"]\n";
    128.         s +=    "tick2\t\t"        +"["+    (Tick2            ==null?"000":Tick2.            GetInvocationList().Length.ToString("D3"))+"]\n";
    129.         s +=    "coTick1\t\t"    +"["+    (CoTick1        ==null?"000":CoTick1.        GetInvocationList().Length.ToString("D3"))+"]\n";
    130.         s +=    "coTick2\t\t"    +"["+    (CoTick2        ==null?"000":CoTick2.        GetInvocationList().Length.ToString("D3"))+"]\n";
    131.         s +=    "lateTick1\t\t"    +"["+    (LateTick1        ==null?"000":LateTick1.        GetInvocationList().Length.ToString("D3"))+"]\n";
    132.         s +=    "lateTick2\t\t"    +"["+    (LateTick2        ==null?"000":LateTick2.        GetInvocationList().Length.ToString("D3"))+"]\n";
    133.        
    134.         print(s);
    135.  
    136.         return s;
    137.     }
    138.  
    139.     //Unity Timing:
    140.     //    1.FixedUpdate*
    141.     //    2.FixedCoroutines*
    142.     //    3.Update
    143.     //    4.Coroutines
    144.     //    5.LateUpdate
    145.     //
    146.     // *1 and 2 may happen multiple times or not at all within one game loop
    147.  
    148.  
    149.     void FixedUpdate() {
    150.         if(FirstTick1 != null)            { FirstTick1();    firstTickSubmitted = true;    }
    151.         if(FirstTick2 != null)            { FirstTick2();        }
    152.  
    153.         if(FixedTick1 != null)            { FixedTick1();        }
    154.         if(FixedTick2 != null)            { FixedTick2();        }
    155.        
    156.         //manually continue all Coroutines added to preInternalPhysicsRoutines
    157.         preInternalRemovalMarker.Clear();
    158.         foreach(IEnumerator ien in preInternalPhysicsRoutines)    {    if( !ien.MoveNext()) { preInternalRemovalMarker.Add(ien);  }    }    //if(preInternalRemovalMarker.Count > 0) { print("ending something");}
    159.         foreach(IEnumerator ien in preInternalRemovalMarker)    {    preInternalPhysicsRoutines.Remove(ien);    }
    160.     }
    161.     IEnumerator FixedCoTick() {
    162.         for(;;) {
    163.             if(FixedCoTick1 != null)        {    FixedCoTick1();    }
    164.             if(FixedCoTick2 != null)        {     FixedCoTick2();    }
    165.             yield return new WaitForFixedUpdate();
    166.         }
    167.     }
    168.    
    169.     void Update() {
    170.         //if no physics Update happened this frame this is the first Tick
    171.         if(!firstTickSubmitted){
    172.             if(FirstTick1 != null){ FirstTick1();    firstTickSubmitted = true;    }
    173.             if(FirstTick2 != null){ FirstTick2();    }
    174.         }
    175.         if(Tick1 != null) { Tick1(); }
    176.         if(Tick2 != null) { Tick2(); }
    177.     }
    178.     IEnumerator CoroutineTick() {
    179.         for(;;) {
    180.             if(CoTick1 != null) { CoTick1(); }
    181.             if(CoTick2 != null) { CoTick2(); }
    182.             yield return null;
    183.         }
    184.     }
    185.     void LateUpdate() {
    186.         if(LateTick1 != null) { LateTick1();}
    187.         if(LateTick2 != null) { LateTick2();}
    188.  
    189.         //reset firstTick at the very end, could also be done in OnEndOfFrame, but why use an additional callback if this is the last we need
    190.         firstTickSubmitted = false;
    191.     }
    192. }
    193.  
    194.  
     
    Last edited: May 25, 2017
  19. Jamate

    Jamate

    Joined:
    Nov 14, 2016
    Posts:
    6
    My last solution:
    - I was trying to delete a prefab (with the first instance created in the Hierarchy) and create a new instance (in the code above).
    - It is well documented, however then I needed to access children of the prefab.
    - I used GameObject.Find("...") method, which used initial Hierarchy only (???) with the deleted prefab = exception <<<<
    - To solve the problem I had to get all the children of the live prefab, test their names, and get the needed <RigidBody> children.

    Is this solution OK?

     
  20. leorin

    leorin

    Joined:
    Apr 15, 2017
    Posts:
    1

    Hippocoder what do you mean by "you dont event need OnCollision" how should i check if any collision has occured?
     
  21. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    By calculating it yourself. You first get all the colliders touching your shape then using getcontacts with contactfilter, do something about it.

    If this is too much then probably it's not for you. It's reasonably advanced I guess.
     
  22. Lesnikus

    Lesnikus

    Joined:
    Aug 29, 2015
    Posts:
    47
    Where is the best way to calculate AI? In my case it's a car's AI. There is a variety of calculations, including sensors's RayCasting. Where it is better to run this code-in Update or Fixed Update?
     
  23. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    I would suggest running it in Update with a tick, ie every half-second or so, update the AI. Some people might recommend a lazy coroutine to do the exact same thing.

    Basically, putting it in FixedUpdate makes no sense at all, unless it wasn't really just AI but a lot of other stuff wedged in there as well that depended on colliders being in very specific places (ie bad AI)
     
    Kiwasi likes this.
  24. DaveLHOz

    DaveLHOz

    Joined:
    Mar 11, 2015
    Posts:
    8
    So are you saying that FixedUpdate() is called at least every time Update() is, so while you may have (at slow frame rates) several FixedUpdate() calls for every Update(), you'll never have a situation where FixedUpdate() is called only once over several frames?
     
  25. Marrt

    Marrt

    Joined:
    Feb 7, 2012
    Posts:
    613
    Exactly the opposite, You'll will have situations where FixedUpdate() is called only once over several frames!


    At least for the default timing settings,
    Fixed Update just checks before Update if enough time has passed and does enough cycles to catch up.
    If you crank up the Fixed update Rate to 200 (0.005s) then you will have 3 or 4 FixedUpdate Calls in a single render frame. If you put it down to 6 (0.1666s) you will get one Fixed Update about every 10th frame.
     
    Bunny83, Kiwasi and lordofduct like this.
  26. AyeJayCee

    AyeJayCee

    Joined:
    Dec 23, 2012
    Posts:
    3
    or.... you could multiply things by time.deltaTime to keep them framerate independant?
     
  27. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    7,532
    https://docs.unity3d.com/Manual/TimeFrameManagement.html

    Update() is executed every frame.

    FixedUpdate() is executed on or about the real time frequency you specify in the Time Manager. Default time is about 3x per second or something. You could have 1,000 frames (or Update()'s) in one second or you could have 1. FixedUpdate() doesn't care how fast your framerate is. It's Fixed.

    If you used Update() then you can always multiply calculations by Time.deltaTime if you want to. The docs explain what it is and how to use it.
     
  28. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    50x per second. ;) 3 physics updates per second wouldn't work very well; FixedUpdate is for physics and really should have been called PhysicsUpdate.

    It's only sort of fixed, and it does care about the framerate. If the framerate is being stressed enough (depending on the settings), FixedUpdate slows down and is no longer real-time.

    --Eric
     
    Quatum1000 and hippocoder like this.
  29. Quatum1000

    Quatum1000

    Joined:
    Oct 5, 2014
    Posts:
    889
    Do you know this physics update is coded in windows? Must be any high resolution timer. Because it's not possible to use ... while { -DoEvents- } until (time-lasttime > delta) because that will cook the cpu. Must be any interrupt timer.
    Any ideas?

    What I like to do is a music software requires a fine variable bpm timing. Then it would be possible to call the midi driver and apply current time to the incoming midi events.
     
    Last edited: Sep 19, 2018
  30. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,338
    It just checks every frame if it's time to do a FixedUpdate yet and does one or more if that's neccessary. Nothing complicated.
     
    Kiwasi likes this.
  31. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,537
    It's not that this is exactly how it's done.

    But this should give you a basic idea of what the logic is behind how FixedUpdate occurs.

    In the example code for Physics.Simulate they process Simulate N number of times per frame based on a timer:
    https://docs.unity3d.com/ScriptReference/Physics.Simulate.html

    This is 'basically' how it works. With the addition of FixedUpdate also being called each Simulate.
     
  32. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    You should probably read some of the rest of this thread. Its been explained a dozen times. It works something like this:

    Code (CSharp):
    1. while (gameIsPlaying) {
    2.     Time.deltaTime = currentSystemTime - Time.time;
    3.     Time.time += Time.deltaTime;
    4.     while (Time.fixedTime < Time.time){
    5.         DoFixedUpdate();
    6.         Time.fixedTime += time.fixedDeltaTime;
    7.     }
    8.     DoUpdate();
    9. }
    Which makes it totally unsuitable for anything that actually requires precise timing, like music.

    Its slightly more complicated, but that is the basic shape of it.
     
    Last edited: Sep 20, 2018
    Bunny83, LaneFox and lordofduct like this.
  33. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,537
    I love that after 4 and a half years of repeating ourselves. We still get to repeat ourselves.

    It's very fun to look back on.

    ... I've been working with Unity for a long time... I don't know how I feel about that.
     
    Bunny83, Kiwasi and LaneFox like this.
  34. Quatum1000

    Quatum1000

    Joined:
    Oct 5, 2014
    Posts:
    889
    Yes.. unfortunately your sample is completely wrong for this behavior.. and code format as well. I'm talking from windows not from unity.
     
  35. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,338
    Wait, what? Windows doesn't have a built-in physics update...
     
    Kiwasi likes this.
  36. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    7,532
    You know as I was posting I was like... this thread is pretty long I bet it's already been answered. Meh, oh well.
     
  37. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    I haven't looked back through this thread. But from memory every other poster was wrong about FixedUpdate.

    The concept is not that difficult to understand. But it seems to trip everyone up.
     
  38. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,338
    I mean the thread title is insane. It's sounds like some conspiracy theory; "This is the truth about FixedUpdate, what they don't want you to know!"
     
    Bunny83 likes this.
  39. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    Physics hate this one simple trick to fix your update
     
    xVergilx and Baste like this.
  40. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,073
    Now can anybody tell us how Invokerepeating will interact with FixedUpdate.

    Will Invoke repeating be invoke between FixedUpdates for very big deltaTime between Update ?
    Or it will do all it's FixedUpdates and IvokeRepeating sets one after another
     
  41. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,537
    InvokeRepeating will update at the nearest 'Update' cycle. So it would work the same as any Update or Coroutine that had a WaitForSeconds on it.

    Noting that if your repeat duration were less than the duration of a single frame, you'd really effectively get a 'once per update' effect.
     
    Bunny83 likes this.
  42. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    We found out FixedUpdate is evil when doing a "animation-driven" game. We are glad we can now turn off Auto Simulate in physic.
     
  43. CPlusSharp22

    CPlusSharp22

    Joined:
    Dec 1, 2012
    Posts:
    111
    If you're using something like this, what do you use in the "Think()" method as a replacement for Time.unscaledDeltaTime? Since you can end up doing multiple "Think()" ticks in 1 Update tick, then Time.unscaledDeltaTime is no longer applicable correct?
     
  44. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,537
    You'd use 'Interval'.

    Since you're writing a think method that behaves similar to how FixedUpdate works, that means it technically has a fixed time step, just like physics.

    The real time difference vs the time step is going to be wildly different... but so it is in fixedupdate as well.

    Note you shouldn't really be doing any animation or anything like that in said think method. But if you need something like change in time you could write your own time tracker... note my old post was really just a simple example of how to start down that path. You can easily add in your own extra features you'd like.
     
    CPlusSharp22 likes this.
  45. CPlusSharp22

    CPlusSharp22

    Joined:
    Dec 1, 2012
    Posts:
    111
    Thanks, duh, I spun around to come back and edit my post but you were quick to respond. Cheers.
    I was previously doing some network simulation stuff for multiplayer inside of FixedUpdate - because it seemed natural to me since you can adjust the tick rate for all FixedUpdates easily. But after reading this thread I switched over to Update.
     
  46. insominx

    insominx

    Joined:
    Jan 23, 2012
    Posts:
    32
    This is a great thread about FixedUpdate but it didn't answer the question I was looking for. Specifically, I wanted to know whether unity would take a full pass over all objects for each FixedUpdate or whether it would call it multiple times on the same object. The answer (which is obvious in retrospect) is that Unity will do a full pass each time. This is needed because each object could be dependent on the results of another object. The test I ran to verify this produced the following results:


    Update from Obj 1
    Update from Obj 3
    Update from Obj 2
    FixedUpdate from Obj 1
    FixedUpdate from Obj 3
    FixedUpdate from Obj 2
    FixedUpdate from Obj 1
    FixedUpdate from Obj 3
    FixedUpdate from Obj 2
    FixedUpdate from Obj 1
    FixedUpdate from Obj 3
    FixedUpdate from Obj 2
    FixedUpdate from Obj 1
    FixedUpdate from Obj 3
    FixedUpdate from Obj 2
    Update from Obj 1
    Update from Obj 3
    Update from Obj 2
     
  47. Renegade556

    Renegade556

    Joined:
    Feb 24, 2021
    Posts:
    1
    Welp, there's my problem with irregular inputs. I thought I had a bad key detection code or maybe a broken key in general. Turns out I had my player controls in FixedUpdate because someone told me it ran at a constant speed faster than Update. Moved to Update and it works great now. Thanks for the clarification!
     
  48. Marrt

    Marrt

    Joined:
    Feb 7, 2012
    Posts:
    613
    Nobody asked for it, but let me explain in detail : )

    The real Problem stems from the hooks that Unity offers. Consider the normal use-case of driving a Rigidbody through physics:

    Every tutorial tells you to fetch input within Update(=renderFrame). Why? Depending on your Timing settings, FixedUpdate (=physicsCycle) might not happen every renderFrame. So if you put event handling for things like OnKeyDown in the physicsCycle, you might miss the KeyDown event entirely. This is because the KeyUp/Down events are only true for a single renderFrame some of those renderFrames might have no physicsCycle. In that case your Avatar misses the KeyDown on the jump key and stay on the ground.

    So the common practice is that OnKeyDown is fetched in renderFrame, the jump key will set some flag that will be consumed in the next FixedUpdate to perform something like ApplyForce(..Impulse).
    Next is the keyword here, because the next physicsCycle will, at best, happen on the next renderFrame, or later. Below you see why, Update(yellow, fetching OnKeyUp/Down) happens after Physics(red). This order is by design because you want the physics system to update its transforms before rendering.
    upload_2021-3-11_9-8-11.png

    But in principle you could fetch the jump key input before the physicsCycle since the Input system already has its final state for this renderFrame.
    As seen in the chart, Unity offers no recurring hooks for that, only Awake, OnEnable and Start. Only Start is usable, because it is the only one that is not immediately called upon Component creation. So I use a script that creates a component at the end of the renderFrame. Then I use the Start of that Component to create a reliable hook BEFORE physicsCycle in the next Frame:
    upload_2021-3-11_10-22-57.png

    upload_2021-3-11_9-52-28.png

    upload_2021-3-11_10-20-17.png --> my hook for input handling

    What is the gain of all of this? Better Input to Physics latency, at least by one renderframe! Noticeable for Inputs that cause immediate effects on physic objects e.g. jumps, dashes and direction changes.

    I hope this is not too confusing.

    TL;DR:
    - Unity needs a StartOfFrame() function
    - I created a semi hacky StartOfFrame()
     
  49. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,338
    With the new Input System, you can set the input system to "Process events manually". Then, using execution order, you can call InputSystem.Update() on the start of both Update() and FixedUpdate(). That way you'll ensure that all the stuff that's ready to go will be read as a part of the frame you're caring about.

    The downside is that things like input.wasPressedThisFrame can't be used reliably in Update anymore, as you might have eaten it in FixedUpdate, so you'd probably have to build some kind of scaffolding if you need to know that kind of information.
     
  50. Marrt

    Marrt

    Joined:
    Feb 7, 2012
    Posts:
    613
    Interesting, can you be more precise which Input System? I lost track of alternate Systems. Do I have to import it via package manager or is it a whole different kind of beast?