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. We are updating our Terms of Service for all Unity subscription plans, effective October 13, 2022, to create a more streamlined, user-friendly set of terms. Please review them here: unity.com/legal/terms-of-service.
    Dismiss Notice
  3. 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

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:
    133
    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:
    2,143
    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:
    133
    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:
    133
    Bumping the topic, there's no bigger bottleneck for us at this moment.
     
  5. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,338
    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:
    2,143
    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,338
    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:
    133
    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:
    133
    Bumping the topic
     
  10. GloriaVictis

    GloriaVictis

    Joined:
    Sep 1, 2016
    Posts:
    133
    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:
    21
    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.
     
    StellarVeil likes this.
unityunity