Playables API performance concerns

Is anyone here actually using the Playables API for anything serious?

It seems like the API is a good fit for those of us requiring more control over the way the animation behaves as well as supporting somewhat dynamic animations without going crazy, however it seems the implementation is riddled with shortcomings and performance issues as soon as you try to scale up.

We are currently using the API for our custom animation system because we were not satisfied with the stiffness of the Animator Controller.
At first we were building a graph with all the required nodes, of course this was really slow, so we ended up disconnecting nodes on demand (i.e nodes with a weight of 0 would end up disconnected from the graph), this improved the animation performance by nearly 10x.

However with this solution, we’re seeing huge spikes happening in our profiling whenever nodes are disconnected and reconnected, see:

This is with about 36 characters with a relatively standard movement + actions graph swapping a previously created AnimationMixerPlayable with a few animation clips for another one.
This 40ms stall in Director.DirectorUpdate which is about 3 times as much as the whole gameplay loop is a big deal for a 60fps game.

Is anyone else seeing something similar? Any workaround?

Thanks

3 Likes

When I did the Performance tests for Animancer I also found that creating playables as they are used and disconnecting (not destroying) them at 0 weight seems to give the best performance except for Sprite animations where creating everything on startup and keeping it all connected is significantly faster. I don’t remember noticing any performance spikes, but I wasn’t really looking for them.

One of these days I’ll get around to doing some much more detailed benchmarks to see how things change in relation to factors like the number of characters and number of animated properties per animation.

4 Likes

Thanks for the reply!
We’re currently in the process of optimizing parts of our game, so we’re really looking for these kind of issues, initially we overlooked this as well, but it became obvious when scaling up the number of playable graphs.

I’m going to be doing more profiling to figure out why exactly we’re getting these spikes and if there’s anything that can be done to mitigate them.
But so far it seems like we will have to keep the “most used branches” in the graph connected at all times, and just connect the less used ones on demand to avoid the performance issues.

I will post more info if I have some, but the state of the Playables API is disappointing, I really wish it was getting more love as it’s the only available low level Animation API (yeah let’s not talk about DOTS Animation :skull_and_crossbones:)
Animation is kind of important in games…

1 Like

any general tips on optimizing Playables? We have similar issue, as we have literally 50-70 animation at the initialization, and we also use Animation Rigging along side, so when we have 25-30 characters - performance is twice worse. Does rapid disconects with latest workaround ( Playables API, Disconnect & Connect not working ) for Playables API still cause a huge spike?

@Kybernetik maybe you have some up-to-date perfomance stats?

I haven’t done any more recent benchmarks than what’s listed on the page I linked.

We reported the performance issue to Unity with some more information about the bug, since we have read only source access, we were able to pinpoint the issue in their codebase, basically each graph change, i.e connect or disconnect would trigger a graph topology change and this would recompute a bunch of stuff each time which gets very slow very quickly for larger graphs (and is usually not needed especially if you just swap a clip with the same curves).
The Animator controller basically uses the same code but is able to get away with not doing that because internally there’s a fast path for connecting and disconnecting playables that does not trigger a topology change.

We thought this would be easy enough to fix so we suggested exposing a public API with a similar fast path to be able to implement dynamic graphs with similar performance to the animator controller, we had to push for a while to get Unity to acknowledge and fix the performance issue in multiple calls and slack messages, we even got as far as getting a custom build of Unity with said public API added!
And then, without going into details, sharks got involved and we were told the fix would be conditional to an agreement that didn’t make any financial sense to us, so we dropped it :slight_smile:

The workaround we ended up implementing is the one I described above, we currently minimize the amount of connect and disconnects that can happen in a single frame to prevent large performance spikes for paths in the graph that are often taken, if you have no memory constraints you could also possibly have multiple graphs that you swap, but we didn’t try this.

8 Likes

Well that’s massively disappointing. Thanks for the insight.

1 Like

@UnityChinny please, comment on this.

1 Like

I will also link Perfomance problems of PlayableGraph, optimizing Animators to this thread, as it seems to have the most impact on the performance right now for our project

1 Like

i’ve created a separate thread just to make sure we can squeeze all juices from playable, if anybody is still interested, please help!

1 Like