Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Have a look at our Games Focus blog post series which will show what Unity is doing for all game developers – now, next year, and in the future.
    Dismiss Notice

Time.deltaTime Not Constant: VSync CameraFollow and Jitter

Discussion in 'General Graphics' started by Zullar, Sep 9, 2016.

  1. tatoforever

    tatoforever

    Joined:
    Apr 16, 2009
    Posts:
    4,268
    @Tautvydas-Zilys
    I really wanna know exactly what did you folk fixed in 2020.2? Cause my characters and my camera movement/rotation now jitters like crazy. It was working fine until 2020.2 (doesn't happen in 2019.4 or 2018). This happens on Nintendo Switch builds but the jittery can also be seen in Editor but hard to notice (looks like a regular editor spike).
    Is there a way to use the old deltaTime value? Or at least simulate it? I'm forced to use 2020 now otherwise I won't be able to do lootcheck submisions for the eStore with 2019. Not only 2020.2 introduced jittery, but also my game run slower too (~5 fps slower) on the Switch hardware. Game is unplayable now due to this jittery.
     
    Last edited: Jul 26, 2022
  2. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    9,887
    The fix was to take delta time values as reported by the graphics driver, instead of measuring the time ourselves. That significantly improved its stability. However, the behaviour in the editor was not changed, as it has multiple windows that get rendered to separately. The fix did go in for Nintendo Switch.

    If you are seeing an issue that happens both in the editor and on Switch, it's unlikely it was caused by this change (because the editor did not receive a fix).

    Now, I don't know why you're getting the jitters. I'd try a few things:

    • Check if the actual frame rate is stable. You can do that by looking at the profiler as it doesn't use Time.deltaTime to display data;
    • If frame rate is stable but you're still getting jitters, try outputting Time.deltaTime values. They should be stable too (as long as the frame rate is solid).
    • If the jittery objects, the camera or anything in their hierarchy have rigid bodies, make sure that interpolation is enabled on them.
     
  3. tatoforever

    tatoforever

    Joined:
    Apr 16, 2009
    Posts:
    4,268
    Frame rate fluctuates in the ~45-55 ish fps range, because is a nintendo switch game.
    I don't have any rigidbody attached to my characters, they move through NavMesh using the Animator.velocity.
    This issue does not happens in 2019 btw, not only the game is slightly faster in 2019 but theres zero jigger/stutter.
    Something to notice, if I use deltaTime to scale camera rotation/positon speed, the camera jitters, but characters do not jitters. If I use smoothDeltaTime to scale camera rotation/positon speed then the camera is smooth but characters jitters.
    Other info that might shed some light:
    - Targetframerate is exposed to users (30,45 and 60fps, default to 30)
    - vSync is disabled
    Anything else that might affect this is either disabled or using Unity default values for the Nintendo Switch platform.
     
  4. Vincent13122

    Vincent13122

    Joined:
    Oct 26, 2014
    Posts:
    138
    Not sure, but are you using lerp to scale the rotation/position speed maybe? That can cause jittering very often if not used in the "correct" way.
     
  5. tatoforever

    tatoforever

    Joined:
    Apr 16, 2009
    Posts:
    4,268
    No, I got a custom Lerping (a safeguard) to avoid overshooting the interpolated value. But if what you say is true it means that Lerp also change behavior in 2020?
     
  6. Vincent13122

    Vincent13122

    Joined:
    Oct 26, 2014
    Posts:
    138
    Well, a lot of people use lerp with just the current and the target value and put in time.deltatime * some other value. But this is not the way you should be doing it, as lerp is linear interpolation. https://gamedevbeginner.com/the-right-way-to-lerp-in-unity-with-examples/ So I would rather use movetowards if this is what youre doing currently. Lerp hasnt changed at all, but maybe you just didn't notice the stuttering before? Sometimes that happens. Also as editor performance has been getting much worse in the last few years, microstutters that may be caused by lerping incorrectly might have gotten more noticeable. But maybe I am wrong and its something else, but maybe not lol
     
    xVergilx likes this.
  7. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    2,920
    As mentioned, Lerp never reaches destination value if percentage parameter (t) is used as dt * value (mathematically);

    Also, worth checking execution order. In short, you'd want to move camera after followed object is being moved.
    Otherwise object may get moved, and there will be a frame skip.

    But to be honest, nowadays we don't use custom camera controllers.
    Just Cinemachine camera with Update Mode set to LateUpdate.

    Smooth like butter. Plus, lots of cool features that you don't need to maintain on your own.
     
    Last edited: Jul 26, 2022
    MartinTilo likes this.
  8. tatoforever

    tatoforever

    Joined:
    Apr 16, 2009
    Posts:
    4,268
    Right but this was working fine until after the change in deltaTime in 2020.2. Like i said earlier, I have a safe guard to avoid overshooting interpolated values when lerping. I don't think it has anything to do with it.
    PS: Camera is the last thing that moves (LateUpdate), characters animates in Update call.
     
  9. tatoforever

    tatoforever

    Joined:
    Apr 16, 2009
    Posts:
    4,268
    The stutter happens only after 2020.2, is very hard to notice in Editor as it look like one of those editor spikes that happens now and then due to the heavy load in the mainthread but on console is a lot more visible and constant.
     
  10. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    9,887
    Time.deltaTime wasn't the only thing that changed in 2020.2: https://unity3d.com/unity/whats-new/2020.2.0

    Anyway, I don't know if the stuttering you're seeing has anything do to with Time.deltaTime changes. Furthermore, it's not clear if the issue you're seeing in the editor is even the same issue you're seeing on Switch. I'd suggest posting on Nintendo development forum about this because console development details cannot be discussed here.
     
  11. tatoforever

    tatoforever

    Joined:
    Apr 16, 2009
    Posts:
    4,268
    Im sure is due to deltaTime because replacing deltaTime by a constant value makes the stutter go away. However this is not the solution because my fps varies a lot and movements/rotations speed and slow down because fps varies a lot.
     
  12. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    9,887
    If that's the case, then taking this to Switch forum is still recommended. Time.deltaTime implementation is highly platform specific. The code that calculates it on Windows is completely separate from the code that does it on Switch.
     
    tatoforever likes this.
  13. tatoforever

    tatoforever

    Joined:
    Apr 16, 2009
    Posts:
    4,268
    Thanks,
    I did that, let's see what they respond.
     
  14. RetroMasters82

    RetroMasters82

    Joined:
    Nov 3, 2021
    Posts:
    19
    The linked thread doesn't address the issue with inconsistent deltaTime. But assuming this issue is solved and you want to update logic in FixedUpdate(), and still have stutter-free visuals, then you will get a useful solution.
    https://forum.unity.com/threads/mot...ion-to-eliminate-fixedupdate-stutter.1325943/

    Btw. @ engine team. It is more FixedUpdate()-related. I see it as a flaw to rely on raw deltaTime/time to time fixed updates or normalizing movement speed (at least there is smoothDeltaTime for that), for the purpose of game engines. Games are not a hard real-time demand, so trying to update something in accord with the wall clock at any given moment tends to add more instabilty than benefit. The timing mechanism for fixed updates should involve an averaged deltaTime instead. An accumulation of averaged deltaTime won't exhibit spikes on any hardware, except for something like long loading times of course. Scheduling of FixedUpdate() calls will still expose algorithmic instability, given how it is implemented, but at least it is something for the better.
     
    Last edited: Aug 25, 2022
    tatoforever likes this.
  15. RetroMasters82

    RetroMasters82

    Joined:
    Nov 3, 2021
    Posts:
    19
    @ engine team and everyone wanting to implement a stable fixed update loop (with motion interpolation):

    For a serious deep dive to a fundamental level, I dedicated an entire Bachelor-Thesis to the stability of fixed update loops (it also includes interpolation, but it is orthogonal to actual stability):
    https://drive.google.com/file/d/1VajBHqmsajsU3Gp1ZYFhAPhavFQJC7wL/view?usp=sharing

    It essentially reveals why "everyone" is implementing fixed time step loops wrong
    and offers better (and also simple) solutions. Now I know the paper is hard to read and is in need for a tldr-version. But to get the gist, just understand the graphical instability examples. Then you will understand the "Hysteresis Loop". It's almost as easy to implement as the "Standard Loop" (the one Unity is using). But it is significantly more stable and has no caveats.

    Like already suggested, we should not use/rely on raw deltaTime values but on a moving average (take around 30-60 samples and everyone is happy). A moving average doesn't introduce a drift to the wall clock (as shown in the paper), and reduces noise significantly. (Also, the data type float is fine for deltaTime, but time/fixedTime should better be double since it accumulates over time. With float, you will get more noise and loss of information in longer play sesssions.)

    In particular, I would suggest the following solution:
    You can improve fixed update and automatically remain backwards compatible to the way Unity works now by doing the following: My suggestion would be to include a moving average filter over deltaTime and having the timing of FixedUpdate() be controlled by the Hysteresis Loop. In the editor, you expose the following variables for users who want to tweak them.

    1. sampleCount
    (for the moving average filter (30 is a good default))
    2. noiseWidth
    (for the Hysteresis Loop)

    Now there are good defaults for the vast majority of users. But when you want to tweak them or go back and make it work the old way, you just set sampleCount = 1 (you get now raw deltaTime) and noiseWidth = 0; Now the loop turns into equivalent FixedUpdate() scheduling of Unity, which basically means it does nothing to eliminate the influence of noise. Instead it gets controlled by it.
     
    Last edited: Aug 28, 2022