I’m wondering what is the best practice for handling characters that most of the time are not needed in my game.
I have 4 separate areas, all of which have various animated characters.
Do I disable them somehow when I leave that particular area or just leave them continuously animating and enabled in the scene.
I haven’t notice much of a slow down yet, but I am planning to add quite a few more animated characters to my scene.
I want to avoid a possible pause and drop in frame rate as I enter a new area, given that the characters would be loaded into memory as I need them.
What approach do people mainly use?
I think the best approaches depend on if the characters need to be recalled after leaving an area, and if they do, how often?
You could, for example, call
DestroyImmediate(someUnusedCharacter) after leaving the area if it’s rare to have them recalled again. Once they return, you have to recreate the, again. However, if it’s left up to the player (i.e the player decides always when and where they go) then I would simply disable them. What that does is saves you some computation. Unity already should be ignoring draw calls for meshs that are not visible by the camera. However, this can be expensive–setting them to disabled saves you a bit on that end. The downside though, is that they’re still taking up memory so if you get really crazy with it, you might see performance degradation from that.
The other suggestion would be, depending on your game of course, would be to “pool” these resources and basically reuse them in each area. If character A looks the same as B, only they different in what you’re calling ‘areas’, then you can simply reuse A to save creation cost and memory of holding both. This is more common with projectiles then actual characters of course, but I thought I’d throw it out there just in case it might work.
I recommend simplicity first. A finished product is better than an abandoned but well-optimized half-project. You may never need to optimize. Unity’s default frustum culling only renders visible objects (details here). If you try to optimize early, you might even hurt framerate by paging stuff in and out.
Enabling and disabling shouldn’t hurt, but the extra complexity might not be worth it. That said, I do it because my characters make a lot of AI checks. If you set up an area with a trigger collider and an array of characters inside the area, you can SetActive() the children appropriately whenever the player enters or exits the trigger.
If you’re using Mecanim, it’s pretty efficient, and you’ll get memory savings, too, if you share animator controllers among multiple characters. If you’re using legacy, profile it to see if there’s any concern.
If you do need to load characters into memory, asynchronously pre-load your assets beforehand. Then when you instantiate characters it’ll be fairly fast.