Developing GUI for mobile apps in Unity3D is one of the harder issues to solve in a satisfactory manner. Drawing from my own experience, the main problems with the built-in GUI system (as of 3.4.1) are:
- Excessive draw calls, more of a problem for earlier devices
- Draws excessive processing power when using GUI, even worse with GUILayout
- Built-in text rendering system is quite limited, difficult to customize
- Not all controls work well out-of-the-box for mobile touch interfaces
To combat this, a variety of approaches have been created, most of which address some subset of the above problems. This blog post in particular will be about a free, relatively new solution called UIToolkit, created by prolific Unity tools developer Prime31, and posted on Github for the community to collaborate around. It’s not the only one, nor the most mature, but it’s been gaining popularity recently and improving significantly since it first launched. I am a contributor to the project, and have mostly worked on text rendering features and fixes.
Many of the various 3rd-party GUI solutions use texture atlases, or sprite sheets to combine multiple textures into one, and that allows for draw calls to be consolidated. Since the draw call budget is pretty limited in early devices, this was one of the biggest reasons to use 3rd-party GUI, but nowadays is less of a problem. In-game GUI still requires high performance, and the overhead of calling GUI, or GUILayout are just too big to overlook even on today’s high-powered phones.
UIToolkit works extremely well with freemium texture atlas generation software called TexturePacker, by Andreas Loew. TexturePacker can automatically fit and combine multiple GUI elements onto the same texture, and export the metadata in a format that is compatible with UIToolkit. Since UIToolkit also allows for automatic switching between 1x/2x textures, which you can get in TexturePacker by changing the scale from 1.0 to 0.5 prior to export. The one caveat is that you’ll need to ensure that your 2x filenames don’t include the “@” symbol, which is unfortunately a different standard than the iOS automatic switching. However, if you’re familiar with 2D game dev with Cocos2d, you might already have TexturePacker, and you’ll be happy to know that you can continue using this great tool for GUI with UIToolkit.
There are a couple of tips I’d offer to Unity devs trying out TexturePacker for the first time:
- Under texture format, just leave this at PNG. You’ll have to reset the texture import settings in Unity after you import it anyway.
- Since UIToolkit requires “2x” appended to the filename instead of “@2x”, you can’t use the SD option in TexturePacker. Instead, I save my file as “…2x”, and anytime I need to re-export, I delete the “2x”, then export at 0.5 scale manually.
- Inner padding of 2 can help eliminate bleed between textures.
- Imported font bitmaps can be confusing because of the extra layer of indirection. The bitmap textures for both SD and 2x sizes MUST have the same filename, so store them in different directories. The exported texture atlases from TP then have different names, and the Angelcode font files should have “2x” appended to HD exported font bitmaps as well.
To address font usage, you can also export bitmap fonts in the Angelcode format, store the bitmap textures in a texture atlas through TexturePacker, and then render out enhanced font glyphs with whatever features you’d like. To get gradients, outlines, and drop shadows easily, I’d also recommend looking into commercial software called Glyph Designer. It does a great job, and is pretty affordable.
UIToolkit is free and frequently improving. The author of TexturePacker also offers free licenses to bloggers if you email him, which is actually how I came about having my own licensed copy.