We are nearing the end of our current project, and as such I am starting to look into optimizations. What better time to share some little-known Unity facts with others than right now?
This post does come with a disclaimer though: do not optimize unless you absolutely have to! Optimization can go on forever, so only do it if there are noticeable issues in the existing code. Otherwise, you risk breaking old code, or at least introducing bugs, for no real payoff. And that doesn't even touch on the maintainability of optimized code.
Fortunately, Unity offers a built-in profiler that can be used to tell exactly where to optimize. Therefore, your optimization strategy should be something like:
- Notice slowdown in your game.
- Use the profiler to pinpoint the exact cause of slowdown.
- Fix only that area, touching as little code as possible!
Now, in the event that you do have to optimize, here are a few tips to help.
Sometimes the profiler doesn't give you enough information, and you need more specifics. This is why Deep Profiling exists. It profiles each individual function call so you can pinpoint exactly what is wrong. However, Deep Profiling has a huge amount of overhead and is often not even possible in larger projects.
Enter Manual Profiling. By using "Profiler.BeginSample()" and "Profiler.EndSample()" in your code, you can profile specific areas that you suspect are causing problems and view the results in the Profiler window. This gives you complete control over your profiling without worry about too much overhead.
Reducing Build File Size
Reducing your final build's file size is very helpful for mobile games. Nobody wants to wait 30 minutes for a game to download, after all. There are plenty of ways to reduce the file size, but here are a few that the Unity pros specifically point out.
Every time you make a build, all its actions are logged in the Editor Log. This can be accessed from the menu at the top right of the Console.
In this file is a ton of info, but you want to look for the assets that are included in the build. You should be able to do a ctrl+f for "Used Assets and files" to find it - it's towards the bottom of the file. This lists out all the assets that are included in the build, their file size, and the percentage of the total build size that they are. This is helpful for determining where to focus your reduction efforts. There's no point in spending 2 hours reducing file sizes on files that are 0.1% of the total build size.
Textures are generally the #1 cause of large build sizes (probably with audio in #2). Here are 2 tips from the Unity docs on how to properly reduce them:
- Use compressed texture formats (DXT on desktop platforms, PVRTC otherwise) where you can.
- Reduce the size of the textures within the editor. Select the texture and set Max Size in Import Settings. The trick is to zoom in on the texture in the Scene View, and then reduce the Max Size as much as possible without any noticeable impact in the Scene View.
This one is minor, but when it comes to mobile games every bit helps. By default, Unity only includes 4 DLLs in the build. System.dll and System.Xml.dll are not part of the 4. Together, they make up about 5mb. So, if you are using them for a minor part of the code, it may be worth it to refactor in order to omit them completely.
Asset Import Format
This is more of a work pipeline optimization rather than a code or build one. I recently discovered that Unity re-codes imported assets into its own internal formats. This means that it treats a .png the same as it treats a raw photoshop file. It simply flattens the photoshop file (if necessary) during the build process and converts it to whatever format it needs. In the past, I've created a file elsewhere, exported it as a .png, and then copied it into the project. By simply saving the raw file into the project, those extra steps can be skipped.
So those are a few of the small optimization tips I've picked up on over the past few days/weeks. If you have one that you feel is particularly useful, please let me know so I can add it to my repertoire!