Search Unity

The truth about FixedUpdate()

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

  1. jpthek9

    jpthek9

    Joined:
    Nov 28, 2013
    Posts:
    944
    Never knew this before! This explains why interpolation between positions in a custom simulation results in stutters.
     
  2. RElam

    RElam

    Joined:
    Nov 16, 2009
    Posts:
    375
    To be fair the input problem you describe exists no matter what method you use, and just gets worse the longer the stalls are. Ultimately, the fix is an input system that works on a recorded input history, rather than polled input states, since the time you ask for the state will always misrepresent the time of input change to some degree. I do like the simple way that Unity does it's input now, it's fine for most games and is super easy to get working, but I do wish they had a better 'mid level' layer to the input system that was timed reliably (high priority thread) or event based so things like well tuned gestures (like fighting game input, for instance) could be done really well.

    And in unity's defense, most engines do not bother doing this, at least in my experience, and suffer the same problem. However, Unity does have the resources to do it right and it's likely time they did.
     
    Kiwasi likes this.
  3. Nition

    Nition

    Joined:
    Jul 4, 2012
    Posts:
    781
    Eh, I dunno. They're better sure, but they all kinda have the same problem as FixedUpdate as well. As of Unity 4.6 at least, Invoke, InvokeRepeating and WaitForSeconds are all affected by framerate.

    If your InvokeRepeating is meant to be calling 10 times/second and you framerate is 2, they call in chunks of several per update (and not 5 every time as you may expect, but anything from 3 to lots, even if your framerate is very steady). Basically the same as using FixedUpdate except that you can specify the tick rate instead of using the one you've set for physics.

    WaitForSeconds on the other hand will only call a maximum of once per frame, so you just start getting less of them as the framerate drops. Still not what you'd want for a fixed tick.

    Invoke and WaitForSeconds also take Time.timeScale into account so that has to stay at 1 if you want the loop to keep going at the same speed.

    I'm interested in what people do successfully use when they really need a fixed update tick. With it being OK to drop ticks if the system really can't keep up of course - we can't do the impossible. Something in C# maybe like System.Timers...? XNA's main game loop worked well in this respect.
     
    Last edited: Jan 27, 2016
    SomeGuy22 likes this.
  4. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    You could just use x/Time.timeScale, where x = the desired time. Works unless you set Time.timeScale to 0.

    --Eric
     
  5. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    Also would break if the timeScale changes after it is called.

    Something like this works without caveats:
    Code (csharp):
    1. IEnumerator WaitForRealSeconds(float seconds) {
    2. float timeStart = Time.realTimeSinceStartup;
    3. while (Time.realTimeSinceStartup < timeStart + seconds) yield return null;
    4. }
    5.  
    6. yield return StartCoroutine(WaitForRealSeconds(1f) );
     
  6. sngdan

    sngdan

    Joined:
    Feb 7, 2014
    Posts:
    1,154
    What exactly is considered physics?

    Let's say I use 2D colliders and rigidbodies on game objects in a simple semi grid based 2D game. I move the game objects directly (transform.posistion) and not with addforce but use the colliders / trigger events for game logic. Would I update the position in Update() with Time.deltaTime or in FixedUpdate()???

    The execution order listed in the first post kind of suggest (in my own interpretation) whenever a game object has a collider and/or rigid body attached, use FixedUpdate() - no matter if you move it by physics (i.e. Add force) or if you move it directly (i.e. Transform.position) ???

    Thx
     
  7. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,531
    Colliders and Rigidbodies use physics.

    Use 'Time.deltaTime' no matter if you're in Update or FixedUpdate. The property returns the correct value when you're in either (it will return the fixedDeltaTime when in FixedUpdate).

    Trigger events don't really pertain to Time.deltaTime, since they're single events. They don't occur on some interval (though might occur many times in a row if collision persists), so there's no deltaTime between collisions recorded for you. You'd have to record that yourself if needed.

    Moving it by physics (AddForce) should ALWAYS be done in FixedUpdate rather than Update (one time events need not apply).

    As for moving it's Transform... this gets into a complicated if case that just blanket saying 'FixedUpdate' is basically the "easy answer". But really what it is, is that by moving a Rigidbody/Collider's transform you're not simulating physics. You're just teleporting it around. So the next time FixedUpdate ticks... it may magically enter or exit a collision with no physical reason.

    If it's a static collider, a problem comes in that it can be slow because the entire collider graph needs to be updated. Though in Unity 5 this was sped up by the inclussion of PhysX v3 (note 2D comes with its own bag of technicalities as it uses Box2D for physics).

    If it's a Rigidbody, well then you have 2 different basic configurations. Kinematic and non-kinematic.

    Kinematic bodies are not effected by physics. So technically it's more like updating a static collider (with out as much over-head, though this over-head difference is again reduced in Unity5).

    Both static and kinematic bodies can really be freely moved around in Update with little consequence to those objects themselves. When animating a rigidbody it's done in the Update loop, not FixedUpdate, and it works fine. The only issue is that if you move the thing and it introduces a collision with a simulated rigidbody... that simulated rigidbody might react strangely.

    Non-Kinematic bodies on the other hand are fully simulated. Moving them around in Update is going to mess up their simulations. The teleporting it around can put it in a state that doesn't exactly make sense... use FixedUpdate all the time.
     
    Last edited: Jan 27, 2016
  8. shawnblais

    shawnblais

    Joined:
    Oct 11, 2012
    Posts:
    324
    Is this true even if it's just a one-time force, like an explosion with impulse force? If so... why?
     
  9. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,531
    Well, one time, isn't going to really matter.

    I probably shouldn't have said ALWAYS... I meant always in the context of Update vs FixedUpdate.

    But if you're in a one time event, then it is fine for the most part. I'm editing my previous post to clarify that.
     
  10. sngdan

    sngdan

    Joined:
    Feb 7, 2014
    Posts:
    1,154
    @lordofduct

    The reason, I came to the conclusion to use FixedUpdate() even if you 'teleport' things around but if they have colliders/rigid bodies attached (i.e. they are involved in collisions / trigger events) was the script execution order.
    Fixed Update
    Collision
    Update
    Render

    Basically if I moved things in update, the collision would only be detected in the next frame

    I am new to unity, not sure if this makes sense?
     
  11. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,531
    Yes, technically it'll happen in next frame. If that's important that you require the collision/trigger event to occur asap when you teleport an object.

    But that's not a reason to always do it that way. It's safe to do it the other way around. It just means the event will trigger at the begining of the next frame.
     
  12. shawnblais

    shawnblais

    Joined:
    Oct 11, 2012
    Posts:
    324
    Thanks LoD, that's what I thought.
     
  13. sngdan

    sngdan

    Joined:
    Feb 7, 2014
    Posts:
    1,154
    Thx - yes, it won't matter much if it is the next frame in most cases. I just wanted to understand kind of in theory how it works, will help me make better choices in practice, hopefully :)

    Basically (with few exceptions like one-time force):
    1. Objects moved by physics engine / non-kinematic -> physics -> FixedUpdate()
    2. Objects directly moved / kinematic / static involved in collisions -> not physics -> Update() or other update frequency (I.e. Coroutine()) or in case the collision needs the be detected in the same frame FixedUpdate()
    3. All other moving / state changing objects -> Update() or other update frequency
    Thx
     
  14. RElam

    RElam

    Joined:
    Nov 16, 2009
    Posts:
    375
    IMO it's best not to get caught up in the idea of what's directly moved by the physics engine and what's not, that's more complex than it needs to be (kinematic does not fundamentally change things). If you're changing mutually dependent data, you'll always get more stable results with a lock-step approach, and I feel I have enough work to do without adding behavioral variance to my game. So for me, moving any gameplay relevant thing defaults to FixedUpdate, then I consider moving it to Update under certain circumstances, not the other way around. So aesthetic elements generally move to Update, or 1:1 camera rotation in FPS. FPS camera rotation is gameplay relevant but non-interactive, so no damage from moving to Update and you get more timely movement from input.

    However, I learned a long time ago that you can get away with a much lower physics timestep than traditionally used. Typically I'd see 60htz used in physics timestep, clearly set to match monitor refresh, but that was because many older systems didn't yet have substep interpolation. With interpolation/extrapolation, 30 is perfectly fine and even heavy action games people can't tell the difference, so it makes a nice target IMO for much of your games logic. Unity defaults to fixed timestep of .02 (50fps), odd choice IMO, and a maximum allowed timestep of .33. Pay close attention to these values, cause that means if you're doing gameplay relevant stuff in Update, that's a pretty massive potential change in how many FixedUpdates you get per Update.
     
    cryptoforge and Kiwasi like this.
  15. sngdan

    sngdan

    Joined:
    Feb 7, 2014
    Posts:
    1,154
    @reelam
    I lost you here, is not the point if you are changing mutually dependent data, you should do it in sync. This could be either FixedUpdate() or Update() but if physics are involved it has to be FixedUpdate() as that's the frequency of the physics engine, so you have to follow it.

    Let's say something like Tetris, I would move the falling blocks directly with transform and not use gravity or forces. I would still want to use collision (hence attach a rigid body and collider) and stop the y movement on collision. I would naturally do this in Update() as I would want the maximum frame rate for smooth movement. I guess I could use interpolation on the rigid body, but why would I do this?

    This is gameplay relevant - so possibly the question is, what are the circumstances you consider when moving from FixedUpdate() to Update()

    The good old assembler c64 days, when you really understood what is going on...no complains, though, not the fault of the tool but my laziness.
     
  16. RElam

    RElam

    Joined:
    Nov 16, 2009
    Posts:
    375
    In Tetris only one thing is ever moving, so sure, the damage from variable timestep is minimized. However, you'd still be doing physics, it's just in code written by you instead of NVidia, and the reasoning for using fixed timestep still apply. What you describe is not unlike a kinematic character controller (which run movement in fixed timesteps in the implementations I've seen), but imagine that you are moving a block to the right and it should start falling in 50ms, and you have a stall for 100ms. The block either slides past where it should have dropped, stops at edge if you write code to detect it, or you write code that substeps your logic. This is why fixed timesteps exist, physics engines aren't magical and need that logic, they're just evolved and robust enough that they have it already, and it's widely used enough that it's accepted as best, even if many users don't truly get why. If writing a tetris game now, for instance, I'd just use a fixed timestep, and alter timescale to speed up the game, then I could just move blocks by, say, 1 unit at a time in my code. Then I have perfect consistency and pretty simple code, just need sub-step interpolation to make it visually smooth (and if using a modern physics engine, then it's done for me).

    These problems don't require stalls either, the last project I was on was a large FPS, and we had bugs directly related to this type of problem regardless of framerate.

    So I guess the short answer to 'why would I do this?' is that it's easier, it'll make a better game, and the player will never know you took the easy way :).

    Mostly aesthetics, hud displays, audio, maybe particle spawning, that kind of thing (still alot of things, really). I mentioned FPS mouse movement cause it's one of the best pseudo exceptions to my rule. But as I said before, I feel running at 30 fixed timestep is fine even for most intense action games, so I don't have alot of reason to move things to Update. 30 is my minimum 'acceptable' framerate, I'm not designing the game to run lower than that, so if 30 is what I need for the logic of the game, then what does running it at 60 get me? (besides the aforementioned inconsistency).
     
  17. sngdan

    sngdan

    Joined:
    Feb 7, 2014
    Posts:
    1,154
    @reelam:

    Thank you for taking the time to explain. This is very helpful.

    My understanding though was that if you have a 100ms stall, it affects everything in the gameloop incl. FixedUpdate() and Update(). This combined with the advice to use Time.Deltatime in both of this functions (earlier posts) makes me wonder if it's not all the same in the end in this particular example.

    I could see how fully relying on the physics engine or not using Time.Deltatime in FixedUpdate() would account for the 100ms stall. The object would simply stay longer in one place but only move in a fixed point/pixel amount per gameloop, hence should not overshoot a static collider...

    I am still not sure I got it 100% but I never really had issues so far, it was more learning than something I have a concrete issue with....on to other things....thx for the replies!
     
  18. RElam

    RElam

    Joined:
    Nov 16, 2009
    Posts:
    375
    No, FixedUpdate is not influenced by framerate in any way, it will always have the same time delta. What another poster was suggesting is that you don't have to worry about writing code that looks at Time.fixedDeltaTime, as Time.deltaTime will return Time.fixedDeltaTime if requested inside FixedUpdate. What was discussed at the start of the thread is when FixedUpdate is run in realtime, which is not consequential in this case (or most cases).
     
  19. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Well, no. If the framerate drop below that governed by the maximum allowed timestep, then FixedUpdate slows down as needed.

    --Eric
     
    djfunkey likes this.
  20. RElam

    RElam

    Joined:
    Nov 16, 2009
    Posts:
    375
    FixedUpdate will get called less with respect to realtime, but it doesn't change with respect to game logic, which is the relevant issue in the above example and what makes FixedUpdate a better choice. I was not trying to suggest it was magical in some way or bypasses Unity's max realtime delta clamps, only that it's your best default location for game logic since it is reliable in that respect.
     
  21. gresolio

    gresolio

    Joined:
    Jan 5, 2014
    Posts:
    17
    "Fix Your Timestep!" by Glenn Fiedler is a very good article, it helps to understand the game loop in general (Garth Smith has already posted this link). I want to add more:

    When should I use a fixed or variable time step?
    An explanation of game loops, FPS and delta time
    Game Loop by Bob Nystrom
    Timestepping by Peter Sundqvist
    MonoBehaviour Lifecycle by Richard Fine (it's the predecessor of monobehaviour_flowchart.svg)
    FixedUpdate simulator :D (I found it here) - beautiful visualization

    p.s. I hope Unity will be open-source one day. At least a code that doesn't covered by any patent or other legal issues. It would be nice if we can learn, contribute and better understand it.

    TLDR: Devs say 30fps is good because the hardware they are designing for is s**t :)
     
    Last edited: Apr 6, 2016
    naknuknik, nxrighthere and hippocoder like this.
  22. Cazmi

    Cazmi

    Joined:
    Oct 2, 2014
    Posts:
    8
    Interesting.

    I figured that using Unity's default fixed timestep (0.02), FixedUpdate() allows 50 phyiscs update per sec (1/50 = 0.02). So whatever framerate you're at, it'll always give you 50 physics updates as opposed to how Update() works which will give you 60 frame update per sec if you're at 60 FPS, so on and so forth.

    I'm kinda wondering if Update is reliable to put your AI logic in, since it's dependent on framerate. Say if you're running at 120 fps, your AI would behave 4x more precise than at 30 fps. On the other hand, if I put the logic inside the FixedUpdate no matter how many framerate you have, it will always be updated 50 times every second.

    What do you think about this?
     
  23. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,531
    Well tying your AI logic interval to your physics interval makes them dependent as well.

    A lot of AI system's I've used, and the one I wrote for myself, instead ticks AI on some interval. Essentially doing the same as FixedUpdate where you calculate frame by frame how much time passed and tick the AI accordingly. This way you can update physics quickly, and AI slowly, etc.

    This can also be good for slow-mo. Say you want the game to go slow-mo AND the AI to be able to react accordingly when in slow-mo, if you tethered a FixedUpdate they'd start thinking slower... but if you could allow them to think at whatever speed you want.
     
  24. Cazmi

    Cazmi

    Joined:
    Oct 2, 2014
    Posts:
    8
    In every frame updates, physics update can occur once, twice, three times, or even none at all - it depends on how many fps you have, if it's too low then physics update will occur more frequently in a single frame update, if it's too high, it will probably take 2 or 3 frame to update the physics.

    Doesn't it make more reliable in terms of logic handling than Update?
     
  25. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,531
    How would it make it more reliable?

    As I stated, you can do the same thing in Update, but not be tethered to physics.

    To tether yourself to the physics, then adjusting speed of either physics OR AI will impact the other.

    Note... I'm not saying tick every update, I'm saying tick like FixedUpdate using update... it's fairly simple:

    Code (csharp):
    1.  
    2. using UnityEngine;
    3.  
    4. public class AIEntity : MonoBehaviour
    5. {
    6.  
    7.     public float Interval = 0.1f; //10 times per second
    8.     private float _t = 0f;
    9.  
    10.     void Update()
    11.     {
    12.         _t += Time.unscaledDeltaTime; //uneffected by slow-mo, fast-mo. Change to 'deltaTime' if you want
    13.  
    14.         while(_t > this.Interval)
    15.         {
    16.             _t -= this.Interval;
    17.             this.Think();
    18.         }
    19.     }
    20.  
    21.     protected virtual void Think()
    22.     {
    23.         //do thinking
    24.     }
    25.  
    26. }
    27.  
    If the amount of time that changed is less than 'Interval' it doesn't update. If it's greater than Interval it does update. If it's doubley greater it double updates. And any unused time is held over until the next update.

    Pretty much exactly like FixedUpdate.

    But NOT tethered to Physics.
     
    CPlusSharp22, Cakeszy, Kiwasi and 2 others like this.
  26. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    Generally speaking you don't want to calculate AI stuff every frame anyway. Every game I've come across does it at a set interval as @lordofduct outlined above. You can blend approaches as well. Our high level AI does goal calculation once per second but individual units still do their FSM stuff every frame.
     
    Kiwasi, Cazmi and lordofduct like this.
  27. Cazmi

    Cazmi

    Joined:
    Oct 2, 2014
    Posts:
    8
    Agreed - doesn't matter your fps, you always get 10 updates in every sec.
    This is a lot cleaner than using FixedUpdate, since you can setup how many times you want your AI to "think" per second without changing fixed timestep settings.
     
  28. meat5000

    meat5000

    Joined:
    Mar 5, 2013
    Posts:
    118
    I know your post was from 2 years ago but this information is still the same. You will find that when FPS is low FixedUpdate frames actually become dropped to save processing for the main thread...so its exactly the opposite of what you said :p

    You can find these limits in the Time Manager (Max Allowed Timestep).
     
  29. RElam

    RElam

    Joined:
    Nov 16, 2009
    Posts:
    375
    I think the part of this that trips people up is not thinking about it in terms of what time 'space' you're working in. With respect to game time, FixedUpdate is 100% consistent, there's no 'fix the physics' or dropped frames. Update is the same, just called with variable timestep, and called once per rendered frame, but still working in game time. Real time is the world you live in, not the game, and thus when determining how much game time to pass the engine uses a clamped real time delta. AFAIK it's no more complex than that. Time passed is clamped for the viewer's benefit, for the same reason a streaming video is paused when buffering.

    Time is not clamped to save processing time, since if you hit your delta clamp, you're one frame past what caused you to hit the clamp. If you're hitting clamp each frame... well, you're likely screwed anyway :).
     
    Kiwasi likes this.
  30. meat5000

    meat5000

    Joined:
    Mar 5, 2013
    Posts:
    118
    Naturally, there is only so much CPU power available but Unity has an option to let you effectively slow down physics time to let the frame processing catch up. The Maximum Allowed Timestep setting (in the Time Manager) puts a limit on the amount of time Unity will spend processing physics and FixedUpdate calls during a given frame update. If a frame update takes longer than Maximum Allowed Timestep to process, the physics engine will “stop time” and let the frame processing catch up. Once the frame update has finished, the physics will resume as though no time has passed since it was stopped. The result of this is that rigidbodies will not move perfectly in real time as they usually do but will be slowed slightly. However, the physics “clock” will still track them as though they were moving normally. The slowing of physics time is usually not noticeable and is an acceptable trade-off against gameplay performance.

    From here. Yes the actual explanation has changed since I read it last and this iteration is the most accurate. FixedUpdate frames are not dropped but if the frame is taking longer to process than the given time limit, Physics Processing is halted.
     
    Last edited: May 13, 2016
  31. RElam

    RElam

    Joined:
    Nov 16, 2009
    Posts:
    375
    AFAIK, that editor setting maps to Time.maximumDeltaTime, which seems to clamp deltaTime (if it did not, I'd call that a bug/design flaw). I think they're speaking of FixedUpdate and physics calls just to help understand what's happening, I don't think they mean to imply it only influences FixedUpdate. I've yet to see indication that it treats the passage of game time in Update or FixedUpdate any differently, again, I'd personally call it a design flaw if it did.
     
  32. meat5000

    meat5000

    Joined:
    Mar 5, 2013
    Posts:
    118
    I have seen it myself. I dont know if the behaviour has been modified since, but several times Using a Debug.Log in Update and FixedUpdate would give results back very different to what I was expecting. I do believe it only affects FixedUpdate as that is what is suggested in the docs. But this is the reason why FixedUpdate is bad for anything but Physics. 'Stopping Physics Time' to let the frame catch up is exactly the same as dropping frames given that Physics Loop executes several times per frame. This is several iterations of that loop that are then not executed. What if you then put input or something like than in FixedUpdate? This will also execute less. You can test this for yourself.
     
  33. RElam

    RElam

    Joined:
    Nov 16, 2009
    Posts:
    375
    I have already addressed input, and think I've explained things well enough. I think people have made erroneous assumptions about FixedUpdate and my experiences over the years have taught me the benefits of fixed vs variable timestep, and where I should use them, and I'm just trying to help people make more informed decisions. If you disagree, then so be it, good luck.
     
  34. meat5000

    meat5000

    Joined:
    Mar 5, 2013
    Posts:
    118
    I have gone against Eric5h5's advice several times, myself ;) I actually wrote a game pretty much entirely using FixedUpdate. To be Frank, it was smooth as silk.

    One has to try these things, right? Cant go taking everything as a given :D
     
  35. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Er, this is gregzo's thread, not mine.... Also, depending on what you were actually doing—the point isn't "never use FixedUpdate" after all—the game may have been running worse than it could have. Relying on subjective perceptions rather than hard data may not be a good idea. e.g., some people seem perfectly OK with a 30fps framerate, whereas I find it annoying.

    --Eric
     
  36. meat5000

    meat5000

    Joined:
    Mar 5, 2013
    Posts:
    118
    I meant this post :) You told me as such time ago and I wanted to try it. Call it an experiment; it was most interesting.
    (For the record though, I do generally stick to your advice. I'd be dumb not to, methinks)
     
  37. Marrt

    Marrt

    Joined:
    Feb 7, 2012
    Posts:
    613
    Big Thanks @Eric5h5 for his continual effort to dispense knowledge into this forum, can't count how many times your posts answered my questions. (and i agree, 30fps is unbearable in any case... ok, maybe for some static puzzle game )

    After reading this thread i admit that i use FixedUpdate() for my AI-logic... and other stuff... lots of other non-physic stuff. But i want to do better and untie these from the fixedTimeStep!

    But how would someone replace "yield return new WaitForFixedUpdate();" with a custom YieldInstruction that behaves the same way (be it with its own customFixedTimeStep). I use WaitForFixedUpdate() all over the place in countless coroutines. When i use WaitUntil() instead it would execute between Update and LateUpdate completely changing the order of things.

    Just to show what i am talking about:
    upload_2016-8-4_10-30-12.png
     
    Last edited: Aug 4, 2016
  38. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,334
    You want it to work like FixedUpdate, but with it's own timestep?

    If you have a large enough timestep (several times the framerate), it's pretty easy. You need a function that gets you from the current Time.time to the current timestep. That would be:

    int currentTimestep = Mathf.FloorToInt(Time.time / timeStep);

    The yieldinstruction would simply store the value of that in it's constructor, and then return false on keepWaiting when that value changes.


    Of course, there are issues. If your timeStep are close to the framerate, two timesteps might have passed when you get back to the yield. You'll have to figure out how to deal with that. There's also the possibility of the division breaking if the game runs for very long - I'm not sure how long it'd have to go for that to happen.
     
  39. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
  40. Marrt

    Marrt

    Joined:
    Feb 7, 2012
    Posts:
    613
  41. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,334
    Whenever Unity checks if it should continue the coroutine, which I believe is every Update? It might be more often, afaik, it's not documented.

    If WaitForFixedUpdate actually happens in the fixed timestep, they're doing some black magic behind the scenes that we don't have access to.
     
  42. Marrt

    Marrt

    Joined:
    Feb 7, 2012
    Posts:
    613
    I think i am getting further and further on thin ice and someone will slap me with reality soon but:
    Then there is nothing that is equivalent of using WaitForFixedUpdate()

    Because you cannot otherwise have a Coroutine continue before physics is processed within a frame (yeah, that is what it is for, obviously). But what i am thinking about anyway?
    Why FixedUpdate for Input and Decisions:
    If you set up a steeringVector or anything at all that affects your Rigidbody, you apply it in FixedUpdate. You set it mostly based on Input, stuff within Update or special Coroutines like different-rate-AI-loops but which are all processed in the main-loop after the physics-loop.
    The effect on the Rigidbody will be applied in the next frame because this frame the physics already happened, so we have a delay. But the Input was already present at the physics-loop in this very frame, it can even be red in FixedUpdate if you only use GetKey (for keyUp/Down you need small a wrapper class or you would miss them or get them multiple times based on the framerate). So we have that additional delay on any if-statement that uses timers to determine if we do something to a Rigidbody (like things that check for Input and a passed cooldown since the last useage, e.g minimum delay between jump inputs). The timer was ready this frame, but the next physic-loop will happen after up to another 20ms.

    Nice, so i just have to write a neat Wrapper called FixedInput that translates my input for the physics-loop and just Update it's flags before FixedUpdate. There is no way of doing anything within a Coroutine BEFORE the internal-physics-update without WaitForFixedUpdate so i use it here. If i want to use my Wrapper in FixedUpdate i need a TickManager (giving me FixedUpdate1 to Update the Wrapper and FixedUpdate2 to replace FixedUpdate).

    So am i right to use the Physics loop for Input considering my above reflections? Or am i seriously misguided? Or do you think: "Why the hell would you care about ~20ms of Input delay?"... i just do... i just do.

    TL;DR:
    I guess the choice of Unity was: Process Physics first because then we have updated positions in Update.

    But because Input has to be tied to Update we always manipulate our Rigidbodys later than we actually need to, introducing additional delay to crucial stuff like touchinput-to-rigidbody-responsiveness and, of course, felt ping in networking.
     
  43. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,334
    Update isn't processed first or last. It's processed as often as possible.

    No matter how often you're running Update, there will be an Update running when FixedUpdate "should" - ie. the time has passed the FixedUpdate timestep. If the Update's done before the fixed timestep, another Update will run. So Unity hasn't made a choice about which to run "first", they're running them when it's appropriate.


    The screen also redraws every Update, and only then*. This means that when you catch input in Update n, and then apply it in FixedUpdate, the input result will be visible in Update n+1. If input was instead caught in that same FixedUpdate, it would still only be visible in Update n+1!


    * Of course, if you have a higher Update-rate than your screen's refresh rate. In which case there's no problem.
     
  44. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    I'm wondering why there's a benefit to running lower physics steps than update, or would appreciate a loop that runs when FixedUpdate doesn't in order to make use of that free processing space.

    Consider 30hz physics and 60hz update: in an ideal world, physics runs every 2 frames. This is a spike in CPU every 2nd frame. This does not mean the game is faster, unless you can take advantage of the space where physics don't update. It's basically just fooling your FPS counter. The frame rate will still potentially look stuttery.

    So I'm not really seeing a benefit to running physics at 30hz, it's not actually going to result in much smoother gameplay unless we can take advantage of when it doesn't run, to run our own stuff on alternate frames.

    Note: I'm not talking about interpolation, I'm talking about how pits and peaks in cpu load will fool an fps counter but still look like turd in reality due to horribly inconsistent frame timing.

    Hopefully someone will get what I'm talking about as there's nowhere near enough coffee in me right now. Anyone know best way to detect when FixedUpdate won't be called?

    edit: I guess since fixedupdate executes before update, it should be trivial to set a flag.
     
  45. Marrt

    Marrt

    Joined:
    Feb 7, 2012
    Posts:
    613
    My head will explode any moment now... i think it will be visible in Update n+2, check this very cumbersome chronology of these two cases below. If i am not mistaken, Unity's Input is set for the whole duration of a main loop, correct?

    Conventional Case: We Update the steeringVector for the Rigidbody in Update based on Input in Update
    Mainloop n+0 -no Input
    -FixedUpdate f+0
    -(physics loop happens)
    -Update n+0

    Mainloop n+1 -jump button GetKey returns true for this frame
    -FixedUpdate f+1 -steerVector is unaffected because input has not been checked yet
    -(physics loop happens)
    -Update n+2 -jump button check results in steeringVector getting a value
    -OnRender doesn't show the new position updated by the force because it has not been applied yet

    Mainloop n+2
    -FixedUpdate f+2 -steerVector from last Update results in Rigidbody getting a force-impulse
    -(physics loop happens)
    -Update n+2
    -OnRender finally shows the new position updated by the jump

    Mainloop n+3
    -(NO physics loop happens occasionally)
    -Update n+3

    Mainloop n+4
    -FixedUpdate f+3
    -(physics loop happens)
    -FixedUpdate f+4
    -(physics loop happens sometimes twice, e.g. when frame rate goes down)
    -Update n+4
    FixedInput Case: I use a GetKey in FixedUpdate to do my rigidbody manipulation
    (note: that won't work reliably for KeyUp/Down without wrapper)
    Mainloop n+0 -no Input
    -FixedUpdate f+0
    -(physics loop happens)
    -Update n+0

    Mainloop n+1 -jump button GetKey returns true for this frame
    -FixedUpdate m+1 -jump button check results in Rigidbody getting a force-impulse
    -(physics loop happens) -Rigidbody takes force into account
    -Update n+2
    -OnRender already shows the new position updated by the force

    Mainloop n+2
    -FixedUpdate f+2
    -(physics loop happens)
    -Update n+2

    Mainloop n+3
    -(NO physics loop happens occasionally)
    -Update n+3

    Mainloop n+4
    -FixedUpdate f+3
    -(physics loop happens)
    -FixedUpdate f+4
    -(physics loop happens sometimes twice, e.g. when frame rate goes down)
    -Update n+4


    @hippocoder very interesting thought! A flag should do, or i didn't learn anything from this thread. Incrementing an int every FixedUpdate and fetching+reseting it in Update should also give you info about if more than one FixedUpdates ran
     
  46. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,334
    Edit: this was a reply to hippocoder!

    That'll only work with a very stable framerate - otherwise the flag might be set, but FixedUpdate will still get called, and you're suddenly getting a big lagspike.

    Honestly, it's also a very strange way to do things. I'm assuming that you'd run some things in Fixed and some things in NotFixed to make things be run regularly, but not as often. But spreading those tasks over consecutive Updates will achieve pretty much the same thing.

    If you really need to never drop below 60, you can have one script that's set to Update first, and one that's set to Update last (script execution order). Record Time.realTimeSinceStartup in the first one, and do work until it's 16 ms past that in the last one. Put all the work that needs to be done in a cyclical list, and you've got a setup that should be pretty safe against lagspikes, and easier to read than one based on global flags and knowledge about the Update/FixedUpdate cycle.
     
  47. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,334
    @Marrt, I believe you're correct. In the case where the button is pressed after Unity's updated the state of Input (some time before Update) and FixedUpdate's up after Update, then there will be two Updates between the key press and the visible reaction.

    Unity could alleviate this by updating the Input state both before Update and before FixedUpdate. This would cause some weirdness - a single keypress would cause two discrete "key has been pressed" events - one for Update and one for Fixed. I guess you could have two seperate Input classes - one for Update and one for FixedUpdate, both of which had their state changed before each of those methods. That'd allow users to poll the most recently available input in both.

    All of this could also be different in the new input system. I don't know how that works, but it's possible that input is registered on it's own thread, and the callbacks are registered as-soon-as-possible.
     
  48. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    @Baste I see what you mean. No, I was just hoping to dump regular tasks somewhere (which are also sliced) - I figured it would be better to run it when FixedUpdate doesn't :)
     
  49. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,334
    hmm, I guess if you take the time since the last Update into account when you figure out how much time you have left over on the 16ms budget, you'd get "have fixed update run since last Update" for free.

    That's probably better than adjusting for FixedUpdate, as how much time Fixed takes varies by a lot, and making the assumption that it's expensive might be wrong.
     
    hippocoder likes this.
  50. Marrt

    Marrt

    Joined:
    Feb 7, 2012
    Posts:
    613
    OMG, i didn't notice!
    But from first glance it just looks like they introduced better abstractions to work with instead of actual engine improvements (like this delightful thread http://forum.unity3d.com/threads/1-frame-lag-with-all-control-input-rage.189300/ , i am sure people can perceive 16ms delay, what is all the fuzz about?) But i won't moan at things i cannot comprehend or improve myself, like fetching mouse-input from any OS and feeding it into your engine (like Unity does)

    EDIT: Use this Tickmanager instead of the below Wrapper, it is the same thing much easier (
    https://forum.unity3d.com/threads/the-truth-about-fixedupdate.231637/page-3#post-3083090 )

    Before we finally derail this thread:
    For now i could just try to code that FixedInput wrapper... i start now:
    (few hours later)
    EDIT, removed old Code, just use this thing:
    https://forum.unity.com/threads/tickmanager.500874/

    Usage: put the script on an any object and it will generate everything to needed to test, you just press W once during play to give the Rigidbodys a 10f impulse

    Result: for a 1x1x1 cube with default rigidbody at a 10F Impulse (moving from left to right), the faster one is driven by FixedInput the other by a steering Vector set at Update
    upload_2016-8-4_19-30-36.png
     

    Attached Files:

    Last edited: Oct 19, 2017