Closed JohnManna closed 1 year ago
Disconnecting weightless playables from their parent usually improves performance (see the Connected vs. Disconnected table here). But for Mixer Synchronization to work it needs to keep all the mixer's children connected and continually modifies their speed to sync their time (because setting the time has other side effects like skipping events).
Having the whole mixer inactive while playing something else shouldn't have any performance cost though (except memory usage obviously). I'll need to look into that.
Also, you might want to check out Animancer v7.4 which has significant improvements to the way you can initialize mixers in code.
Are you sure you aren't modifying the mixer.Parameter while the state is inactive? I haven't looked at the code yet, but that could be causing it to recalculate all the child weights which is particularly expensive for 2D mixers (though I'm hoping I can improve that using the jobs system for Animancer v7.4).
Thanks for the info, I'll check it out.
I've looked through the code and it appears ApplySynchronizeChildren
is what is costing so much. I believe this is what you are referring to above.
Are you sure you aren't modifying the mixer.Parameter while the state is inactive? I haven't looked at the code yet, but that could be causing it to recalculate all the child weights which is particularly expensive for 2D mixers (though I'm hoping I can improve that using the jobs system for Animancer v7.4).
Yes, if (moving)
protects against that, I just added a breakpoint to verify it.
Disconnecting weightless playables from their parent usually improves performance (see the Connected vs. Disconnected table here). But for Mixer Synchronization to work it needs to keep all the mixer's children connected and continually modifies their speed to sync their time (because setting the time has other side effects like skipping events).
Yeah, I have seen a big improvement with performance with nodes being disconnected. What I don't understand is why is the parent mixer node still running updates when it has been removed from the graph? I understand that its children will still be connected to it but if the parent node is not part of the playable graph, shouldn't updates be skipped?
Adding a simple condition of if (!IsPlaying && !needsMoreUpdates) return;
before ApplySynchronizeChildren(ref needsMoreUpdates);
in MixerState.Update(out bool needsMoreUpdates)
has greatly improved performance. Maybe this has some bad side effects like you mentioned, but for my use case seems ok. In an extreme use case of 128 animators with 10 nested mixers per each, the prepare frame step is now only 0.07ms. Without this change it was 5.50ms.
Change the if
at the start of ApplySynchronizeChildren
to:
if (Weight == 0 ||
!IsPlaying ||
_SynchronizedChildren == null ||
_SynchronizedChildren.Count <= 1)
return;
I only did a quick test but it seems to work fine. The side effects I mentioned were only for having some of the mixer's children disconnected, but if the whole mixer isn't playing then there obviously isn't any point in having the mixer update the speed of its children every frame and the mixer will get added back to the update list when it gets played again.
Fantastic, basically same change I tried. Works great.
Animancer v7.4 is now available with this fix.
Environment
Description
It seems inactive
LinearMixerState
nodes are still processed causing a large performance loss with scenes with a high number of active Animancer components. This has been observed by wrappingUpdateAll(_PreUpdatables, info.deltaTime * info.effectiveParentSpeed);
with a profile sample and by observing theLinearMixerState
nodes withinprivate void UpdateAll(Key.KeyedList<IUpdatable> updatables, float deltaTime)
. Shouldn't these nodes be removed from_PreUpdatables
? Its strange because the playableGraph does remove these nodes when they are inactive.Reproduction
Spawning 128 characters with this code requires 0.60ms to process the inactive
LinearMixerState
even though the idle state is playing. Replacing this node with aAnimationClip
improves performance bringing the cost down to 0.07ms.With the mixer
Without
Graph of time of profiling
Code snippets: