0
\$\begingroup\$

I've been banging my head against a wall this past while over how I might create menu's and menu components in unity from text file. I would normally just build my own extended panel/label classes etc in c# and then use the properties loaded from file on instances of those extended classes. I have a properties loader but I cant seem to get my head around making a gui class that's dynamic from reading unitys documentation. Has anybody ever tried this?

Here's an example of a menu definition file.

    <GUI_Menu: mainMenu >
    <Atributes>
        <> Type : Menu
        <> Position_X : 0
        <> Position_Y : 0
        <> Height : Vanilla_Property_Screen_Height
        <> Width : Vanilla_Property_Screen_Width
    </Atributes>
    <GUI_Panel: menu >
        <GUI_Button: play >
            <Atributes>
            <> Position_X : 50
            <> Position_Y : 50
            <> Type : Button
            <> Height : 50
            <> Width : 100
                <Description>
                    <> Key : desc_Play
                    <> Description_Address : Main\\Text\\Menu\\desc_Menu.xml
                </Description>
            </Atributes>
            //button action/button data/description
        </GUI_Button>
        <GUI_Button: options >
            //button action/button data/description
        </GUI_Button>
        <GUI_Button: mods >
            //button action/button data/description
        </GUI_Button>
        <GUI_Button: texturePacks >
            //button action/button data/description
        </GUI_Button>
    </GUI_Panel>
</GUI_Menu>

<GUI_Menu: play >
    <GUI_Panel: load-New >
        <GUI_Button: loadSave >
            //button action/button data/description
        </GUI_Button>
        <GUI_Button: newGame >
            //button action/button data/description
        </GUI_Button>
        <GUI_Button: multiplayer >
            //button action/button data/description
        </GUI_Button>
        <GUI_Button: voxelEditor >
            //button action/button data/description
        </GUI_Button>
    </GUI_Panel>
</GUI_Menu>

EDIT: Note that it is important that the menus are loaded from a definition file that is easy to read and write by a human being as custom menu's and GUI's/components will be supported through modding.

\$\endgroup\$
  • \$\begingroup\$ Where are you stuck? It seems to me that you could - p.e. for a button - create your own, XML serialisable button class which is just a few properties and one PaintGUI() method. Your parent script, that handles the loading of the definition file could then just de serialize all objects, and call PaintGUI() in its OnGUI(). Remember though that Unity will get a whole new UI in a few weeks/months. \$\endgroup\$ – kat0r Jun 16 '14 at 22:42
  • \$\begingroup\$ I'm not sure how I'd implement this. The main idea is that certain menus/menu components are held in memory when needed eg: main menu is held till the a save/game is loaded then they are discarded and the inventory/stat/pause/etc menus are loaded up ready for draw calls to be made by the manager. I've never made an XML serialisable class. my experiments so far require me to add and remove components from the ingame camera object as and when needed which to me is dirty and causes data tracking issues also my data structures get messed up. I had to write a class to flush buttons from the object. \$\endgroup\$ – That Homeless Guy Jun 16 '14 at 23:10
1
\$\begingroup\$

Firstly, you'll want to use some sort of serialization. I've found that the XmlSerializer class in the .NET framework is an excellent tool for this, that allows for relatively simple and powerful control over precisely what gets serialized, and how. Plus, XML is reasonably easy to debug, since the data is saved in plain english (assuming you set it up that way).

Unity's GUI system, as it is now, does not function on a basis of "components" or "objects." At least, not on the surface (any of the parts of the engine that users have access to). However, with the 4.6 update that is supposedly coming sometime this Summer, the in-game GUI will be changed pretty dramatically (more info on that here), so don't get too used to the way Unity's in-game GUI works, right now.

Basically, the entire thing functions on a select few callback methods/functions (depending on whether you're using C# or UnityScript/JS) that are executed by the engine, at certain points throughout the game's lifetime. For GUIs that are in-game, the vast majority of these calls will be to the OnGUI method/function, which is actually a shared nomenclature over much of Unity's systems (including EditorWindow, which is an editor class, which means it isn't run in-game).

Within the proper callback function, you can make calls to static methods in the GUI class, and the GUILayout class. There are a number of minor differences between these two classes, but the biggest difference is that the GUILayout class automatically manages the positioning of GUI elements, where with GUI, you have to define the Rects (rectangular area objects) in which the GUI elements are defined.

If you want to save parts of GUI elements, what you would want to do is to create a class that will represent how your GUI element will look and function by holding the data needed to make the method calls that would otherwise "manually" create that object, if they were written directly in the OnGUI method.

So, for example:

public class GUIButton
{
    string text;
    Rect position;
    delegate someMethod;
}

The delegate could be replaced, depending on your implementation, by making the class into an interface, but then the data would be more complex to integrate, and I can't even begin to fathom how one would serialize an anonymous class. Delegates are easily changed at runtime, as well, so you could easily change the functionality even within a single button object, without re-creating it, and removing the old one.

Beyond that, again, you'd need to handle serialization/deserialization, somehow, which is a bit of a task in itself. I'll link a few places you might want to go for more info here:

Unify Wiki Article- Saving and Loading Data: XmlSerializer

GUI Class Tutorial

GUILayout Class Tutorial

EDIT In the newest version of Unity (4.6), the GUI has been overhauled. While the legacy system is still in place, the new system is component-driven, and provides a significant boost to performance for complex GUIs, and is (in my opinion, at least) FAR easier to use. They have reportedly optimized this system to vastly reduce draw calls, among other things. You can find out more about the new system here:

Unity - What's New

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.