Hello, I have been looking around all day to see if I could find a way to manually update the animator by a controlled amount of time by script, but I’ve failed to find anything to that effect.
I have tried to do this, but it both prints read “GameTime”…
This is/will be used for something else (and is experimental, as evidenced by the enum name), and at the moment, doesn’t do anything, as you saw.
You can either disable the component, and update it manually.
animator.enabled = false;
then
animator.Update(deltaTime);
Or you can set the speed to zero, and do something like this when you want to update:
animator.speed = 1.0f;
animator.Update(deltaTime);
animator.speed = 0.0f;
Both will give slightly different results, and it depends what you want to do.
The second one will animate every frame, but time will not advance.
This also works with the state machine visual debugging, whereas disabling the animator will break the visual debugging.
It’s also worth noting that using any of those approaches means your animators will run single-threaded, so there may be performance issues.
Could you elaborate a bit more on the Animator.Update being single threaded? Is the normal Animator Update method multithreaded? Would trying to optimize by using Animator.Update not be a good idea? Please help.
The normal Animator Update does one pass where it updates all the Animators, splitting these animators in batches that will be evaluated using all available threads.
Calling Animator.Update will run the update for that Animator right away, so if you do this for all your Animators, then the other threads will sit idle in the meantime.
If you are developing for PC, PS4, Xbox One or any platform that has multiple cores, it’s unlikely that you’ll be seeing any gains by manually updating the Animator.
Alright, thank you for clearing that up. I was hoping to save on some performance by changing the update rate of each Animator depending on the distance from the camera. I guess it would be useful if there was a method to add the Animator to a list of animators that are to update with the batch.
There’s a clever user who figured out that you can put multiple animators in one PlayableGraph, connect an AnimatorControllerPlayable to each Animator, and then manually update the PlayableGraph.
Doing this will execute the Animators as a batch, which will take advantage of all threads. It requires a bit more work than just dealing with the Animators directly, but it might address your use case.
I implemented this technique as well and it feels like an abuse of the playables system. Is there any roadmap item for supporting batched update of a set of animator playables?
Did that user post about it somewhere publicly available? I have an entirely playables based system so I’m wondering if it would be worth changing my implementation. In particular, I’m wondering if Unity will multithread graphs containing PlayableBehaviours given that they don’t seem to get multithreaded at the moment.
Not that I’m aware of, I discovered it myself after some experimentation. I should note that I do not use any MonoBehaviours in my implementation as I am using the ECS and needed to avoid them.
I put multiple animators in one PlayableGraph, and then execute Evaluate() in update.But as seen in the profile, PrepareFrame() can only be processed in the main thread.How can I make PlayableGraph.Evaluate execute multi-threaded?
I tried doing this (adding ~800 Animators to a PlayableGraph with the idea of controlling update frequency for performance).
In profiling, with the graph being used, CPU-Animation gained ~2ms (from 7ms), Evaluating the graph added ~3-4ms (from 4ms) to CPU-Scripts that wasn’t there previously.
So … huge loss of performance from implementing this with everything updating as frequently as it was previously.
Splitting those 800 entities across two graphs and updating them alternately roughly brought performance back to where it was originally. Hrm.
I am pretty new to the playable - but is there a way to use existing Mecanims and playables to exactly “lod them up”, using PlayableGraphs to update them each “X” frames based on distance and that’s it? Or I should be working on a custom implementation of Mecanim for that reason, making transitions and choosing clips from code for that reason?
@ZERO025 :
I tried using your method of having a single playable graph, as it looked to be the cleanest. But I couldn’t get it to work. The graph gets created, and it looks correct in the Visualizer, but my avatars wouldn’t animate. We do use an AnimatorOverrideController? or could it be the version of Unity / AnimationRig? I’m on 2021.3.5f1, with Rigging version 1.1.1
We’re also using RigBuilder, so not sure if that might also be a source of complication.