Game development tips: improve level loading in Unity
Staff Writer By: Sergio Rosa (nemirc)
Say you've been working on a level for your game for a long time. You added all of your models, textures, sounds, lights, scripted elements, and all. But then, when you begin loading your level, you notice the game "hangs" for a little bit before you can continue playing. This is a very simple tip, but very useful in case you need to improve performance when loading levels.
Recently, I was working on a level for our current game. My goal is to have fast loading times (no more than 3 seconds) so it feels like the game doesn't stop between level change. After testing a few times, I couldn't get the results I wanted, so I went inside Unity to try different things until I got the result I wanted.
The level is a cave with different structures and rock formations, so my first option was to minimize the amount of textures I had. Basically, I tried to leave custom textures just for the most important objects of the scenes (architecture elements that you need to climb or interact with, in one way or another), and use the same material (and thus the same texture) for the rest of the cave and rock formations.
Thanks to this change, two things happened: first, the level loaded faster, and it was smaller. However, I still got that "bump" in the middle of the gameplay. By the way, the whole thing was a combination of testing compiled versions, and testing the level inside the editor, using the Unity profiler window (there was a huge spike in the profiler graph at some point right before the level became playable, so I figured there was something wrong there).
I then found out that I could gradually activate objects in Unity to ease the level transition. The logic is this: every single object in the level has to be "initialized" before it can do anything. This applies to lights, static objects, characters, animated objects, and all that. This means that, whenever you load a level, it is trying to initialize all the objects at the same time.
So the solution was simple, but also time-consuming: I had to configure the objects so that they are activated (and thus, initialized) gradually, after the level is opened. Unity still needs to load the entire level, but it doesn't need to init all the objects, just those that are already activated.
Rather than activating one object at a time, I opted to reorder all the objects in different groups, and then I made a script that would activate those different groups gradually. The actual groups can vary from one game to the next, so you'd need to figure out the best order for your level. In my case, I first activated the lights, then my character, static meshes, then smaller meshes. Had my level included animated elements, I would have activated those somewhere in the middle. I offset the activation between them by a fraction of a second, so it's hardly noticeable, and I also use a "fade in" effect, so everything is being activated while the screen is still dark.
As I said before, this was just a very quick and simple tip, but extremely useful. I don't know if you'd done this before, but in case you haven't, know this simple trick can help a lot. I hope you found this useful, and I'll be back with more game development tips soon. By the way, right now I am working on a short video game side project, and my plan is to rely on the Unity Asset Store as much as possible, as a way to show how useful the Asset Store is when it comes to making your own short games.