Search Unity

Fixed update dissonance

Discussion in 'Physics' started by WillSykes, Dec 16, 2015.

  1. WillSykes

    WillSykes

    Joined:
    Nov 11, 2014
    Posts:
    1
    Hi all,

    I thought I would mention a rather surprising issue that i have been chasing down for the last 2 days (and have now "solved")

    The issue has to do with ensuring that you get exactly 1 fixed update per render when running your game at 60fps with vsync. Surprisingly, by default there are some serious problems (even if your game is super optimal and uses very little frame time).

    The problem is this:
    Unity cleverly tries to ensure that the correct number of fixed updates have been called for the current frame time. therefore. if you set your fixed update time to 1/60 and then run a frame at 60 hz, the update will be called once. If you run a slow frame (30 hz) unity will automaticly call the fixed update twice. all good so far...
    BUT
    when you set your fixed update time to 1/60. there is some small floating point error in the value you set! this means that over a period of time, eventually (for me about 5 minutes) the total of all these 1/60 s added together does not come out at exactly the current frame time. this results in unity intentionally running 2 fixed updates 1 frame and none on the next frame! this looks exactly the same as dropping frame rate only you are actually still running your render at 60fps!

    So i tried several things, interestingly the default unity fixed update is 1/50 which results in a skipped frame every 5 frames..a very odd effect which looks almost like 60fps but with an ugly jerk to it..it baffles me that unity defaults to 1/50...what monitor refreshes at 1/50?

    anyway my solution is fairly easy to implement and may help somebody else out who is having the same problem:

    put this code in an update function of an object in your scene

    Code (CSharp):
    1. float newTimeDelta = Time.deltaTime;
    2. newTimeDelta = Mathf.Clamp(newTimeDelta, 1.0f / 120.0f, 1.0f / 50.0f);
    3. Time.fixedDeltaTime = newTimeDelta;
    this code synchronises the fixed update with the vsync and results in lovely 60fps physics.

    If anybody has any alternate suggestions please let me know (I have to say that I am surprised that I couldn't find anybody else posting about this issue)
     
  2. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,508
    Very nice trick!

    The drawback I can see is that the physic behavior depends on the actual frame rate. So the same situations in two different devices might result in different gameplay. For example if one of the devices handles 120 Hz and the other can't barely reach 50 Hz, then the gameplay might be quite different among them.