GUI structure best practice

Hello. Similar to a prior post, I’m interested in a best practice approach to the UI needs for our game. I’ve read through the lengthy list of posts, I’ve been able to play with Unity and learn a bit about the immediate mode approach to GUI rendering.

To that end, I have a couple general questions and a suggestion for how I think I want to approach the UI for our game. The information given to previous posters was helpful in narrowing down the questions for me, just looking to fill in the gaps.

Premise: Building a game that has basic sections of UI screens (splash, main menu, in-game UI hud, typical stuff). The in-game UI hud will have a LOT of windows (inventory, missions, help, character doll, navigation aids, chat, etc.) Those parts seem ok and well traveled.

One additional note is that there will be sub-sections of the game that are very different experiences with their own custom UI; lastly, these sections will be loaded dynamically, and we don’t know until runtime what they are ( as in, the sub-games will adhere to an interface, but not require that the master game know about their internals).

In my initial work with the UI, I had set up each major screen to be its own level. Looking at posts, this seems to be a heavy handed approach and one that might not be the best practice in the long run. SO…

With that in mind, my thinking is:

1.) Create a game object that remains persistent across level loads that is a master UI controller of sorts. This will have a script associated with it that stores information such as the current “UI screen” that is being displayed, and transition code (if i want to dissolve once screen, load another, code for doing that lives in here).

2.) For the various major UI screens, create a game object with attached script that “registers” with the master UI script so that it can be made active/inactive.

3.) For dynamic UI screens, from dynamically loaded levels, have UI scripts embedded in the loaded level that also register with the master UI so that they can be switched to once loaded (and the prior active UI screen made inactive).

Mostly, the key that I want to achieve with this or something better is having a clear, structured UI. I know that any game object in the world can have a GUIText or OnGUI call made, though there will be times when UI elements will not want to be drawn and so I’d like to have a way to track UI state globally.

Is this reasonable? Is there a better way? Using former UI systems, this approach worked well when we had logical “screens” of UI, but Unity’s UI approach is different enough that I figured I’d ask.

Thanks for any insight.

This can be difficult to do properly with Unity’s GUI system. It all depends on how detailed you want to get.

To create a basic UI manager just involves storing either delegates that point to GUI rendering methods in other active scripts, or references to classes that implement a standard Interface or base class that allows you to ensure that your GUI rendering methods will be called without issue.

Then on every OnGUI call for your manager, you loop through the list or table, calling the GUI draw methods as you need.

You can get crazy with Reflection tricks as well, but in our testing that is not as useful as one would think.

The main thing is to build it so the system itself enforces proper usage. This also has the side effect of improving the readability of your code down the road.

I also (of course) recommend you check out our GUI system GUI-eXtended (GUIX) as our system already handles this, and completely wraps Unity’s GUI system, among many other things to improve code quality and productivity.

At the very least, looking at how we chose to solve these problems for our system may help you out in designing your own system.

Another note is have the least amount of logic code in your GUI blocks as possible. Running lots of logic in GUI blocks quickly leads to buggy code, and poor readability.

Good luck!

-Jeremy

That’s very helpful information, I’ll take a look at GUIX. I definitely want to build it as you mentioned, so that’s it very clear and readable and enforces proper usage.

I fear that over time the ui could get out of hand to where there are tons of state variables in scripts all over that modify the UI and have to be tracked down and changed when ui elements are modified/added/removed. Perhaps that’s unfounded.

Thanks very much for your response, it gives me a starting point to research further. I don’t want to go down a path of architecting a UI structure that goes against the grain of the engine itself.

Not unfounded at all. This is actually the primary reason why we created GUIX internally for our own use.

Storing simple GUI state data along with the data the interface is actually showing to the user in the same place was adding a good deal of friction where it isn’t needed.

Immediate-mode GUI can be very useful for certain things, and the rendering works great. But when things start to grow in a full project, that’s when coupling problems can occur.

As long as you keep your data, main logic and GUI state all separate using a clear and solid framework, you should be fine.

-Jeremy