Hi everyone,
I’m quite new to Unity, nevertheless I already landed a well paid job to create a game using Unity. Therefore I’m quite anxious to do things well on first attempt, without too much trial & error.
It is a Point & Click adventure type of game, with lots and lots of detailed environments, scenes, characters and requisites. And - how could it be any different - my client wants it to run smoothly on mobile (at least tablets) as well.
Now I wonder what the ‘best practices’ for this type of game, and for handling large amounts of 2d-graphics in Unity, are.
Currently I am using TexturePacker in conjunction with Unity’s native 2D-Tools, and it’s working quite well, so far at least.
Nevertheless I already have a lot of texture-atlases, as even the background-image for one single environment almosts consumes an entire 2k-atlas. So I wonder what to do (and what not to do) to avoid overloading the game’s memory consumption as development progresses.
Should I use many individual Unity-scenes to have my many texture-atlases be distributed (and seperately loaded) as evenly as possible? Also regarding the DrawCalls? Or is there any other way to handle which atlases are stored in memory (and when they are drawn) at what time?
Currently I have one big Unity-scene holding all the environments, and the main-camera just jumps from one to another. But, continueing like that, I probably end up with gigabytes of graphics loaded and drawn all at once, don’t I?
Any tips, please?
Have you actually checked to see what these resources use in memory? Typically what I do is have an internal XML file with SpriteID, and SpriteLocation inside. Then when the game first starts…usually pre-MainMenu scene where the engine logo is shown and the company logo is shown, etc. I will load those assets into a Dictionary<ushort, Sprite[ ]>.
Then when I need a specific sprite I will call Game.GetSprite(spriteID, spriteSubID). This ensures that I am always being handed a reference to an existing Sprite in memory, as opposed to reading it in from file on demand, resulting in a a new Sprite every time, which will consume even more memory.
I would try reading all your sprites into memory, and using profiler to check where your usage is at. If it is rediculously high, then what you could do is load them from file on demand…but keep them stored in memory in a separate dictionary after they are loaded in. So when you call GetSprite, it first checks if that sprite has already been loaded and is in your dictionary, if not it will load from file instead, add to dictionary, and return. When you change scenes, you could queue a clearing of the loaded sprites dictionary resulting in a GC later on or I think you can use Object.Destroy() on the Sprites as well.
Thank you very much. Ouh, that sounds like a Game-generated-from-Code approach. But currently I’m heavily depending on the Unity-editor, placing and distributing all Sprites in there. That works well for my game, since rarely any sprites are being generated. All graphics in the game (environments, characters, requisites…) are already “there” and are placed in the scene by hand.
Currently I’m doing a prototype of the game. If that is approved of (and it most probably will), I will license Unity Pro and thereby attain the profiler. Perhaps it might be better if I just finish the prototype and don’t bother about memory until I have the profiler (= the hard facts).
You already have the profiler with Unity Personal Edition. Window > Profiler.
Oh, this is new, isn’t it
?! So good to know. I will go profiling right away!