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

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.

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).

1 Like

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.

Bumping the topic, there’s no bigger bottleneck for us at this moment.

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?

1 Like

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.

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.

I am not sure if that would help the performance, as the performance is same bad with Speed 0 :frowning:

Bumping the topic

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).

1 Like

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.

1 Like

private void OnBecameVisible()
{

}
private void OnBecameInvisible()
{

}

Script needs to be in same object mesh render / skinned mesh renderer