I find myself complaining a lot about the GUI systems that are designed for game use, rather than for typical desktop apps. For some reason or other, they all seem to fall short in one or more ways. Part of this is perhaps a quest for optimal performance, but I suspect a lot of it is also that game developers traditionally don’t have much familiarity with other types of application and don’t always appreciate the best way to approach complicated user interfaces.
What I look for in a graphical user interface system is the following:
Separation of logic and presentation
You don’t want these mixed together for reasons that are covered extensively elsewhere, but one good reason is so that an artist can change the layout without requiring any code changes. Unity’s immediate mode GUI completely breaks this idea, because the layout is decided by the flow of the code. If you have 10 buttons in order and you want to swap the order of buttons 2 and 3, that’s a code change. Want to arrange some elements horizontally instead of vertically? That’s a code change too. Unity does try hard to give artists independent control over the GUI theme and styles but the interface there is so clunky (and bugged) as to make it a joke. Really, you want to be able to specify layout either in code or from data, you want to be able to have the theme as data too, and you want a narrow interface (eg. IDs and callbacks) between the layout and the logic. Web development’s trio of HTML, Javascript, and CSS are actually close to the ideal here. (Mozilla’s XUL is even closer.)
Must be easy to read information from it.
It should go without saying that you’d want to be able to query the state of the interface, eg. to get the current content of an edit box before sending the text to the app when the user presses Enter. Strangely, this is one of the cases that the aforementioned UnityGUI makes awkward. You can’t query an edit box because it doesn’t exist in a queryable form. Instead you have to cache the return value of the call that displays the edit box so that when you get the KeyDown event for the Enter key, you know what was in that box. It reminds me of some of the more awkward moments of MFC where you would create a control variable which would hold the value of the control – but at least Microsoft provided an editor UI to hook them up and to place the control onscreen. Unity, which has editor UI for pretty much every single other aspect of their engine, expects you to do this part all by hand. Microsoft also at least had the courtesy to offer an alternative route via looking up the control with GetDlgItem – not possible in Unity’s UI.
Must be easy to write information to it.
Some libraries pride themselves on how easy it is to create a dialog window. Take a look at this example from kytten, a GUI system for Python’s pyglet games library:
dialog = kytten.Dialog( kytten.TitleFrame("Kytten Demo", kytten.VerticalLayout([ kytten.Label("Select dialog to show"), kytten.Menu(options=["Document", "Form", "Scrollable"], on_select=on_select), ]), ), window=window, batch=batch, group=fg_group, anchor=kytten.ANCHOR_TOP_LEFT, theme=theme)
Great! Now… how would I change that label later? When kytten creates a new control it may be just a wrapper for several sub-controls, maybe nested, so you have no easy way of getting a reference to the Label even by trying to traverse the hierarchy. The result is that you can’t really change the content of the label if you construct it in this way. Instead you can construct important controls first and pass them in later, but that gets incredibly unwieldy.
If you just want to show some buttons on the screen then it’s ok to have a ‘write-only’ GUI. But most systems require something more dynamic than that.
Doesn’t force low level issues and optimisations on you.
Unity’s built-in UI is widely regarded as awful for anything other than rudimentary use, so naturally many 3rd party systems have appeared as alternatives. One favourite is NGUI. By all accounts it is very capable. Yet to use it you need to get familiar with texture atlases, nine-sliced sprites, tiled sprites, bitmap fonts, etc etc. These should be implementation details hidden from you unless you explicitly need to access them. Worrying about slicing the texture should be outside the app and in the data somewhere. Creating a texture atlas should be done automatically by the software unless you have a strong desire to override it, and the same goes for generating a bitmap from a font. Tiling vs. stretching should be an option on an Image. Another Unity UI alternative, EZGUI, seems to have the same issue, which suggests that these are problems exacerbated by Unity somehow.
Decent selection of controls.
Pretty much every GUI system will offer you a button, a text label, editable text, and an image. Great – but it’s not long before you start needing more than that. For example:
Pretty much every desktop UI offers all these controls. Pretty much every game UI I’ve tried recently lacks one or more of them. I lost count of the number of times on my last project I was asked by a designer to use a drop-down list and our UI didn’t provide it. And trying to hack grids and tables in via horizontal and vertical boxes is a recipe for pain.
And no, Unity, creating new controls is not the same as grouping a few existing controls together.
Conclusion
Strangely, the various GUIs available for C++ developers seem quite capable: CEGUI, SFGUI, GWEN, etc. For some reason the more laborious task of making a decent GUI in C++ etc has been done while those with normally more productive languages struggle on with half-baked solutions. Why is this? Why do developers in other languages accept that UI has to be a chore? And what can we do about it?
I completely agree. Most UI libraries for games are lacking, and I’m sick of writing my own, which is why I’ve started to use Awesomium(.com) for my XNA project. Awesomium is a Web-UI for native apps. Basically, you write HTML, Javascript, and CSS to produce a very functional UI for your game. It can even be used with Unity: http://labs.awesomium.com/unity3d-integration-tutorial-part-1/ I would recommend using it in combination with jQuery and jQueryUI.
If only Awesomnium wasn’t commercial! It would solve a lot of people’s problems. I think the fact that they charge for it is a good indication that the free alternatives are pretty poor by comparison.
what about harnessing qt? is it really that inconvenient performance-wise?
It’s usually hard to get systems like Qt into games, because it’s more of an application framework than a GUI library. Game developers usually need something they can embed within their existing app, providing hooks to perform the rendering. Qt provides ways to render 3D graphics within its own windows, but it’s less clear how you perform the inverse.