noobtuts

Unity GUIs

Foreword

In this article we will learn how to work with Graphical User Interfaces(GUIs) in Unity. We will start with very easy things like Buttons and then go into more complicated techniques like the difference between Unity's GUIs and GUILayouts.

A simple Button

So let's start right away and create one of the simplest and most important GUI elements, the Button. After creating a new Project in Unity, the next thing to do is to create a new Script in the Project area:
unity-create-script
Let's name the script Guis. After it's created, we open it by double clicking it. It shows us the following code:

using UnityEngine;
using System.Collections;

public class Guis : MonoBehaviour {
    // Use this for initialization
    void Start () {
       
    }
       
    // Update is called once per frame
    void Update () {
       
    }
}

This is the basic Unity code for each component that we create. The Start and Update methods are two of many methods that Unity calls in each component.

Unity has a special function like that, just for all GUI stuff. It's called OnGUI. Let's add the OnGUI function and remove the Start and Update functions since we don't need them in this article.

using UnityEngine;
using System.Collections;

public class Guis : MonoBehaviour {
    void OnGUI() {

    }
}

Note: make sure to name it exactly OnGUI, and not onGUI or similar.

So let's make a Button. It's surprisingly simple in Unity, it can be done with one line of code:

using UnityEngine;
using System.Collections;

public class Guis : MonoBehaviour {
    void OnGUI() {
        GUI.Button(new Rect(0, 0, 100, 50), "MyButton Text");
    }
}

The GUI.Button function just needs to know the area and the caption of the Button. The area was created with new Rect(0, 0, 100, 50). It means that the Button is at the position 0/0 (which is at the top left of the screen) and it has a width of 100 pixels and a height of 50 pixels.

In order to see something, we now add the script to a GameObject in our scene. Since by default Unity creates a Main Camera, we might as well use that one. Simply drag the Guis script from the Project area onto the Main Camera object in the Hierarchy like this:
unity-add-script-component
We can find out if it worked by selecting the Main Camera (just click it) and then taking a look in the Inspector area. It should look like this:
unity-added_script
Thats it, let's press Play to see our Button:
unity-button
That was easy!

Now even though we click it, nothing really happens. In our Guis script we still need to find out if the Button was clicked. This is even simpler because the GUI.Button function returns true if it was clicked. Let's open the Guis script again and check the return value:

using UnityEngine;
using System.Collections;

public class Guis : MonoBehaviour {
    int counter = 0;

    void OnGUI() {
        if (GUI.Button(new Rect(0, 0, 100, 50), "Clicked: " + counter))
            counter = counter + 1;
    }
}

After saving it and pressing play again, we can see the effect that happens after clicking the Button.

More simple GUI Elements

There are a lot more things that we can do with Unity's GUI system. Let's add a few more very simple things to our script:

using UnityEngine;
using System.Collections;

public class Guis : MonoBehaviour {
    int counter = 0;

    string text = "ABCD";

    bool toggle = false;

    void OnGUI() {
        // simple button
        if (GUI.Button(new Rect(0, 0, 100, 50), "Clicked: " + counter))
            counter = counter + 1;

        // simple label
        GUI.Label(new Rect(0, 60, 150, 50), "I love noobtuts.com");

        // box without any text
        GUI.Box(new Rect(0, 120, 150, 50), "");

        // box with text
        GUI.Box(new Rect(0, 180, 150, 50), "BoxText");

        // text field (always needs a string to save the text)
        text = GUI.TextField(new Rect(0, 240, 150, 50), text);

        // toggle
        toggle = GUI.Toggle(new Rect(0, 300, 150, 50), toggle, "Toggle Me");
    }
}

Note: since we want them below each other, we always change the second paramter in the Rect a big (the y position).

Here is how it looks after pressing play:
unity-more-guis
Incredibly simple. It's most likely as simple as a GUI system can be.

So many Rects

With the previous methods we always used a Rect to set the area of the GUI element. For the lazy, Unity offers a alternative that works without Rects, called GUILayout. When making GUIs with GUILayout, Unity calculates the optimal position and size of the GUI elements automatically.

Let's try it out! At first we remove the Guis component from our camera again (click on Main Camera, look at the Inspector area, right click on the Guis component and remove it). Then we create a new Script, let's name it GuisLazy and add it to the Main Camera. When opening the Script, it looks like this:

using UnityEngine;
using System.Collections;

public class GuisLazy : MonoBehaviour {
    // Use this for initialization
    void Start () {
       
    }
       
    // Update is called once per frame
    void Update () {
       
    }
}

We remove the Start and Update methods just so it looks cleaner, and then we add a OnGUI method again:

using UnityEngine;
using System.Collections;

public class GuisLazy : MonoBehaviour {
    void OnGUI() {

    }
}

Okay, time to use Unity's GUILayout techniques. We start with a simple Button again:

using UnityEngine;
using System.Collections;

public class GuisLazy : MonoBehaviour {
    void OnGUI() {
        GUILayout.Button("Layout Button");
    }
}

Note how this time we use GUILayout.Button instead of GUI.Button and without the Rect parameter.

Let's press play and see what it does:
unity-guilayout-button
As we can see, Unity found the perfect position and size for our Button automatically. Let's add one more GUI element to see the true power of Unity's GUILayout:

using UnityEngine;
using System.Collections;

public class GuisLazy : MonoBehaviour {
    void OnGUI() {
        GUILayout.Button("Layout Button");
        GUILayout.Label("This is a slightly longer Label than before");
    }
}

Save, press play again and be amazed:
unity-guilayout
Unity realized that we want to draw two GUI elements. Obviously we do not want them on top of each other. Last time we positioned the Label below the Button by modifiying the Rect y value. This time we have no Rect, and Unity automatically realized that it has to place the Label below the Button and give both elements an equal width so it looks properly. Awesome!

Summary

We just learned the fundamentals of Unity's GUI system. There are a lot more features like drawing images, creating moveable windows, creating scrollviews and so on. With the knowledge that we have now, all of those other elements are straight forward to understand. An in-depth documentation about them can be found in the Unity script reference at GUI and GUILayout.