Performance Hit When Using Animator Override Controllers (Unity 2D)

Hey, I am developing a game where the player character swaps between multiple weapons throughout. Because of this, I opted to use the Unity Animator Override Controllers to swap between different spritesheets whenever a weapon is picked up or swapped out. However, because of the amount of things to animate (2 arm objects animated across 9 individual animations for each weapon), the performance of the game takes a hit occasionally when picking up/swapping between weapons.

Is there a method of improving the performance here? I am still fairly new to making games, and am not great at performance optimization yet.

1 Like

From what I’ve read, you can optimize your scripts by making sure you are caching any calls/functions whenever possible, and avoid openingly using GetComponent in update or void functions (instead, cache them in Awake).

This link describes the process

I do this for the most part in my scripts, it’s just that when my animator is swapping between various animation overrides it can cause a huge uptick in memory usage (at least that’s what I think is happening). The animation override controllers are kept inside a serialized private array in a script attached to the player, so I don’t think it’s trying to create an expensive reference to them each time

To get a better idea of what is the true source of the problem, you have to use the profiler, and ideally on a build b/c sometimes the Editor says slightly false information. Unity - Manual: Profiler overview

Since you mention memory, you should also check the Memory Profiler: Unity - Manual: Memory Profiler module

It is extremely difficult to speculate about performance problems, outside of trivial examples, without the aid of the profiler. When you post on the forums about performance, you should include screenshots from the profiler.

Alright, well here is a reference for the profiler on my end. For the most part, everything but GC Allocated in Frame is fairly constant from the looks of things. GC Allocated per frame is spiking every time I grab an object off the ground (which swaps the animator override controller), going from 368 bytes to 2 kilobytes

8454233--1121753--upload_2022-9-20_21-58-9.png

You should use the button in lower left of the screenshot, “Take Sample Playmode” - it will tell you where you actually have memory allocated.

You should also profile your scripts to find what exactly is allocating the garabge. This may require to turn on Deep Profiling (warning: laggy), which provides a LOT more information.

All in all, however, 2KB isn’t very much. A single tiny texture can be that size. Any garbage generation isn’t ideal but sometimes it’s the price you have to pay.

I’m sure it’s not the worst performance hit, but it’s just concerning. Currently, the game is set to run at 60 FPS, and collecting objects/swapping items can cause a small but noticeable performance dip (usually a dip goes to around 54 to 50 fps, again not major but I want to figure this out now rather than deal with it later).

My question is not why it’s happening, but if there are ways to minimize the performance hit of swapping between animator override controllers that utilize separate spritesheets.

That’s why I recommended Deep Profiler. Usually the “why” is directly related to “how” to avoid. It may be an inevitable cost of using the override controllers, it may not. It could be completely unrelated or secondary to the apparent cause. Personally I roll my own Finite State Machines and use the asset Animancer to Play(clip) directly to avoid the opaque parts of the Animation system, but that may be completely unnecessary for this case if the profiler can give you more detail.

Okay, so I wanna apologize real quick. I misunderstood what you meant by “Memory Profiler”, and just assumed you were referencing the item I showcased above. After doing some research, I realized it was a package that is listed as “experimental” in Unity 2020.3

Either way, I have just installed it and learned that one of my spritesheets was listed as 32 MB, while almost every other sprite sheet was around 4.0 MB or less. I then learned that the sprite sheet still had read and write enabled from an earlier test with sprite swapping, as well as RGBA formatting instead of Automatic.

I still need to test how this affects performance, but thank you for your insight. I apologize again for misunderstanding.