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

Is there a possibility to skip animator frames with distance? For example using PlayerLoop?

Discussion in 'Animation' started by GloriaVictis, Nov 2, 2020.

  1. GloriaVictis

    GloriaVictis

    Joined:
    Sep 1, 2016
    Posts:
    123
    We are updating from 2017.4 into 2019.4 LTS, our game is an open-world MMORPG and so we cannot clamp the number of players can see on his screen, and moment, where those are 200+ players, is not that uncommon.

    For that reason, we had to sacrifice the FixedUpdate to be happening every 3rd Update frame (so no regular physics on client side happening) which allowed us to play the distant animator on the FixedUpdate. Yet, of course, there should be some more efficient way, which we could steer the animators update tick.

    Anyone aware of an solution of that matter? I had a hope that PlayerLoop could be helpfull, but I cannot think of solution allowing us to custom the behavior to update frequency based on distance from the camera.
     
  2. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    1,765
    The Update Rate example in my Animancer plugin shows how you can easily update animations at a custom rate based on distance to the camera.

    I've never tried it when using Animator Controllers, but you might be able to get a similar result by setting the animator.speed = 0 and calling animator.Update(deltaTime).
     
    GloriaVictis likes this.
  3. GloriaVictis

    GloriaVictis

    Joined:
    Sep 1, 2016
    Posts:
    123
    Sadly, putting animator.speed = 0 at Mecanim gives the exactly same performance in comparsion to animator.speed = 1 so it doesn't give any improvement on that matter.

    I am working at Unity since 2012 and I just cannot believe there's no such basic optimization as this possible.
     
  4. GloriaVictis

    GloriaVictis

    Joined:
    Sep 1, 2016
    Posts:
    123
    Bumping the topic, there's no bigger bottleneck for us at this moment.
     
  5. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,305
    Complete guess here but don't animator controllers create a playable graph? The one you can get from the Animator? So maybe you can do something like call SetTimeUpdateMode to change it to manual updates and tick the graph yourself?
     
    itadakiass likes this.
  6. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    1,765
    I haven't tried the update mode specifically, but trying to change anything else in that graph doesn't work because all the playables are marked as read-only to give an exception if you try. You can change the output, but that achieves nothing because it gets reverted immediately by the next animation update. So you could try it, but I wouldn't expect it to work.
     
  7. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,305
    Ya being readonly makes sense.

    Might be a bit of work in an existing game, but animation clip LOD is a thing and often overlooked. Bake LOD clips with reduced density which you can automate. Last time I tested this it had a significant impact performance wise, plus it all still smoothly interpolates.
     
  8. GloriaVictis

    GloriaVictis

    Joined:
    Sep 1, 2016
    Posts:
    123
    I am not sure if that would help the performance, as the performance is same bad with Speed 0 :(
     
  9. GloriaVictis

    GloriaVictis

    Joined:
    Sep 1, 2016
    Posts:
    123
    Bumping the topic
     
  10. GloriaVictis

    GloriaVictis

    Joined:
    Sep 1, 2016
    Posts:
    123
    An update, I have found the way which overall is pretty hacky but somehow works. When an animator is far from the player, we make it disabled and update using
    Animator.Update(Time.time - _timeOfLastRandomUpdate);

    It makes Animator much less thread-based, but on the mass scale that's the only reliable way we found out to be working on optimizing it, but it requires to update Animator every 5th frame or less to make it work (of course the lowest frequency the better).
     
  11. itadakiass

    itadakiass

    Joined:
    Nov 11, 2017
    Posts:
    15
    well it actually worked. I set the animator's PlayableGraph update mode to manual and than update it myself by calling Evaluate() every X seconds.
     
unityunity