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
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.
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?