Search Unity

  1. Are you interested in providing feedback directly to Unity teams? Sign up to become a member of Unity Pulse, our new product feedback and research community.
    Dismiss Notice

Animations in eternal loops slows down over time

Discussion in 'Animation' started by Kragh, Jan 16, 2020.

  1. Kragh

    Kragh

    Joined:
    Jan 22, 2008
    Posts:
    651
    Hi there :)

    So my students and I have build an arcade machine, to showcase our productions to the rest of the school. Works great. It has a "hub" from where all games are launched. Also great. But this hub has some UI elements which are animated from the Animator system. Colors, and transforms and such. Those run forever. When the hub has been running for a couple of days, those animations begin to fail. First they'll get slower. And slower. Until finally they are so slow, that they seem to not animate anymore. That happens around day four.
    Everything else is still very responsive. Inputs to the hub, and general "Update" functions seem to run normally. So it is not the project itself that slows down, only the animation system internally.
    My own little theory is that each cycle will increment some internal state. And then memory, over time, will get filled with garbage, which the garbage collector fails to clean, due to it not being de-referenced. Something.

    My fix for now is to destroy, and recreate certain UI elements (Having made them into prefabs that I can load from "Resources"), when they have been running for some time. But it still feels like a hack, that should be unnecessary.

    Anybody having a clue what's going on, and how to fix it for real? Is it a bug, or is it simply would is to be expected when having a game/project just run for days on end?
     
  2. davidnibi

    davidnibi

    Joined:
    Dec 19, 2012
    Posts:
    349
    Are these days virtual days?
     
  3. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    5,538
    It's probably due to the timer.

    Untiy's animations uses an internal timer to keep track of how long it's been playing. That timer just increments forever.

    This means (approximately) that every frame, Time.deltaTime is added to the time value. Due to how floating point numbers work, that starts breaking as the total time is larger, as the number can't handle that much precision.

    Now, this should be fine for a couple of days if Unity was using a double to store the time, but they might be using a float. I'm not sure.


    One way you could try to fix this in a less destructive way is to grab the Animator's playableGraph, and set it's time back to 0 at regular intervals. If the problem is an clock internal to the Animator (which is what it sounds like, since other things are responsive), that should fix things. You might want to also reset the time on all of the playables in that graph.
     
  4. Kragh

    Kragh

    Joined:
    Jan 22, 2008
    Posts:
    651
    No... These are just days. Real days. It is a physical machine, running a Unity project.
     
  5. Kragh

    Kragh

    Joined:
    Jan 22, 2008
    Posts:
    651
    Makes total sense :) Thanks for the insights into why this might happen. It works for now, so I may just move on.
     
  6. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    1,769
    The Playable GetTime and SetTime methods use doubles so I would assume it's all doubles internally.
     
  7. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    5,538
    I would too, but when I tried to emulate the problem manually using doubles, adding 1/60 to 60*60*24*10 (10 days) gave an imprecision of -5,43271504171994E-11, ie. almost nothing. So this shouldn't be noticeable after just 3 days with such a setup.

    Floats, on the other hand, is completely unable to add 1/60 seconds to 2 days (the result is just 2 days), so honestly my test might be off?
     
  8. davidnibi

    davidnibi

    Joined:
    Dec 19, 2012
    Posts:
    349
    If you can use seconds in a game (which you can), can you not just create a virtual clock and reset back to 0 (like how a digital clock works), when it reaches obvious 60ths/12ths, or does this come under the eventual bloated floating point precision as Baste says?

    Code (CSharp):
    1. realMinute = System.DateTime.Now.Minute;
    2. realHour = System.DateTime.Now.Hour;
    3. actualMinute = float _minute % 60;
    4.  
    5.  
    transferred to physical meshes:

    Code (CSharp):
    1.  
    2. hourHand.transform.localRotation = Quaternion.Euler(0, 0, (realHour * 15 * 2) + 15);
    3. minuteHand.transform.localRotation = Quaternion.Euler(0, 0, (realMinute * 6));
    etc
     
  9. neojsm2

    neojsm2

    Joined:
    Jun 27, 2017
    Posts:
    3
    We are having the exact same problem.
    How did you solve this problem?
     
  10. Kragh

    Kragh

    Joined:
    Jan 22, 2008
    Posts:
    651
    I actually didn't fix it in the hub itself. I don't know how I would, as it seems be because of the internal clock that is based on floats. And floats are too unprecise for animation timings and such the higher they are.
    But what I did do was let the arcade hub create a new Windows process of a new instance of itself, and then close down. It does so every night at 5:30 am, unless it registers usage. When it hasn't been in use for 5 minutes, and 5:30 is reached (Or surpassed), it shuts down, and restarts. Works great. But... it is a hack ;)
     
unityunity