Thursday, July 12, 2012

UnityGUI: Tip and Tricks

I suspect I am alone when it comes to praising UnityGUI. I was rather pleased to hear that more work has gone into UnityGUI in the Unity3D 4 Release. I know that most people don't like it for one reason or another, but I believe there are a few reasons to LIKE it that most people don't consider.

1. Text Editing. Have you tried to implement a reasonable text field widget using other toolkits? UnityGUI already does it perfectly, on all platforms. No third party GUI toolkits have the same capability. If you want your home and end keys to work, or allow the user to use a mouse to select text... UnityGUI is the best (and only?) solution.

2. Customisation. It is trivial for a programmer to create compound widgets which can be reused all over the place. Eg, grids, table views, validated text fields, etc.

3. Skinning. It is so simple to apply a different skin to your GUI, and to get artists to build a custom skin for you.

4. It's standard. You know you can use it anywhere and it will work the same. You know you can take someone else's GUI code and make it work for you without major changes. We need a standard to allow interoperability.

There are still some valid issues with UnityGUI.

It's hard for non-programmers to use, and it's hard for programmers to make nice looking interfaces. This is primarily a tool and workflow issue, and solvable. To get started with your own solution, make your GUI scripts run at edit time using [ExecuteInEditMode], so you can visualize changes. Expose all your variables in the inspector so they can be tweaked and visualised.

The performance issue is harder to solve, but I would posit that if you're experiencing major performance problems and you blame UnityGUI, then you're just Doing It Wrong. The path to UnityGUI enlightenment starts with using only one OnGUI call per scene. Next, remove your GUILayout calls, and write some layout manager code which can size and position your widgets just once, or when needed at runtime. Set your variable once, and don't use GUIStyle instances, just refer to a custom style in your skin. This will help you get the best performance out of your GUI code. It also helps to remember that while people are staring at your GUI, they're probably not worried about dropping to 60 instead of the usual 200 or more! :)

Finally, do yourself a big favour and learn how the event system in Unity3D works. You can get the current event using Event.current. Once you have that information, your code can make smart decisions about which methods to call and which events can be short-circuited.


Nevermind said...

No, you're not alone. Although I don't have much praise for UnityGUI I mean, it's really horrible - all the third-party "solutions" are actually worse. The likes of EZGUI and NGUI are perfect when all you need is a couple of pretty buttons or maybe text labels, but they break on any complex GUI just like UnityGUI does, and their way harder to extend.

I've written more than one "sane" wrappers over UnityGUI, that turn it from programmers-only "immediate" to designer-friendly component-based GUI. It's pretty easy to do and works realy good.

And as performance goes, we recently tried NGUI on our iOS project. It was SLOWER than my UnityGUI wrapper.

Valentin Simonov said...

Meh... no vector graphics. Still useless. Waiting for Scaleform.

Popular Posts