Almost all the recipes in this chapter involve different interactive UI controls. Although there are different kinds of interactive UI controls, the basic way to work with them, as well as to have scripted actions respond to user actions, is all based on the same idea: events triggering the execution of object method functions.
Then, for fun, and as an example of a very different kind of UI, the final recipe will demonstrate how to add sophisticated, real-time communication for the relative positions of objects in the scene to your game (that is, radar!).
The UI can be used for three main purposes:
- To display static (unchanging) values, such as the name or logo image of the game, or word labels such as Level and Score, that tell us what the numbers next to them indicate (the recipes for these can be found in Chapter 1, Displaying Data with Core UI Elements).
- To display values that change due to our scripts, such as timers, scores, or the distance from our Player character to some other object (an example of this is the radar recipe at the end of this chapter, Displaying a radar to indicate the relative locations of objects).
- Interactive UI controls, whose purpose is to allow the player to communicate with the game scripts via their mouse or touchscreen. These are the ones we'll look at in detail in this chapter.
The core concept of working with Unity interactive UI controls is to register an object's public method so that we're informed when a particular event occurs. For example, we can add a UI dropdown to a scene named DropDown1, and then write a MyScript script class containing a NewValueAction() public method to perform an action. However, nothing will happen until we do two things:
- We need to add an instance of the script class as a component of a GameObject in the scene (which we'll name go1 for our example – although we can also add the script instance to the UI GameObject itself if we wish to).
- In the UI dropdown's properties, we need to register the GameObject's public method of its script component so that it responds to the On Value Changed event messages:
Figure 2.1 – Graphical representation of the UI at design time
The NewValueAction() public method of the MyScript script will typically retrieve the value that's been selected by the user in the dropdown and do something with it – for example, confirm it to the user, change the music volume, or change the game's difficulty. The NewValueAction() method will be invoked (executed) each time the go1 GameObject receives the NewValueAction() message. In the properties of DropDown1, we need to register go1's scripted component – that is, MyScript's NewValueAction() public method – as an event listener for On Value Changed events. We need to do all this at design time (that is, in the Unity Editor before running the scene):
Figure 2.2 – Graphical representation of the runtime of the UI
At runtime (when the scene in the application is running), we must do the following:
- If the user changes the value in the drop-down menu of the DropDown1 GameObject (step 1 in the preceding diagram), this will generate an On Value Changed event.
- DropDown1 will update its display on the screen to show the user the newly-selected value (step 2a). It will also send messages to all the GameObject components registered as listeners to On Value Changed events (step 2b).
- In our example, this will lead to the NewValueAction() method in the go1 GameObject's scripted component being executed (step 3).
Registering public object methods is a very common way to handle events such as user interaction or web communications, which may occur in different orders, may never occur, or may happen several times in a short period. Several software design patterns describe ways to work with these event setups, such as the Observer pattern and the Publisher-Subscriber design pattern.
Core GameObjects, components, and concepts related to interactive Unity UI development include the following:
- Visual UI controls: The visible UI controls themselves include Button, Image, Text, and Toggle. These are the UI controls the user sees on the screen and uses their mouse/touchscreen to interact with. These are the GameObjects that maintain a list of object methods that have subscribed to user-interaction events.
- Interaction UI controls: These are non-visible components that are added to GameObjects; examples include Input Field and Toggle Group.
- Panel: UI objects can be grouped together (logically and physically) with UI Panels. Panels can play several roles, including providing a GameObject parent in the Hierarchy window for a related group of controls. They can provide a visual background image to graphically relate controls on the screen, and they can also have scripted resize and drag interactions added if desired.
- Sibling Depth: The bottom-to-top display order (what appears on the top of what) for a UI element is determined initially by its place in the sequence in the Hierarchy window. At design time, this can be manually set by dragging GameObjects into the desired sequence in the Hierarchy window. At runtime, we can send messages to the Rect Transforms of GameObjects to dynamically change their Hierarchy position (and therefore, the display order) as the game or user interaction demands. This is illustrated in the Organizing images inside panels and changing panel depths via buttons recipe.
Often, a UI element exists with most of the components that you may need for something in your game, but you may need to adapt it somehow. An example of this can be seen in the Displaying a countdown timer graphically with a UI Slider recipe, which makes a UI Slider non-interactive, instead of using it to display a red-green progress bar for the status of a countdown timer.
In this chapter, we will cover the following recipes:
- Creating UI Buttons to move between scenes
- Animating UI Button properties on mouseover
- Organizing image panels and changing panel depths via UI Buttons
- Displaying the value of an interactive UI Slider
- Displaying a countdown timer graphically with a UI Slider
- Setting custom mouse cursors for 2D and 3D GameObjects
- Setting custom mouse cursors for UI controls
- Interactive text entry with Input Field
- Toggles and radio buttons via toggle groups
- Creating text and image icon UI Drop-down menus
- Displaying a radar to indicate the relative locations of objects