Introduction to Unity UI – Part 3

In this final part of our three part tutorial series, you’ll learn how to integrate Unity UI into a working game.

5/5 1 Rating · Leave a Rating
 
Please note, this is a STATIC archive of website www.raywenderlich.com from 08 May 2019, cach3.com does not collect or store any user information, there is no "phishing" involved.

Update 20th December 2016: This tutorial was updated to Unity 5.5 by Brian Moakley. Original post by Kirill Muzykov.

Creating sliding menus in Unity is now a snap!

Creating sliding menus in Unity is now a snap!

The third and final part of this series all about Unity’s UI.

In Part 1, you created a menu scene, complete with an adaptive background and neatly controlled graphical elements, thanks to expert-level use of anchors, pivot and other cool tricks.

Part 2 was all about animating buttons and actions to make your game uber-interactive.

Now you’re going to build on these skills to round out your understanding of Unity’s UI, but you’re not going to stop with a fancy new menu. You’ll also migrate the RocketMouse game scene from the old legacy GUI system to the new UI system!

Getting Started

Start off by opening the Unity project at the point where you left it at the end of Part 2. If you tinkered with your old project file to a point beyond recognition — or skipped the last part — you can download the starter project for Part 3 here: Rocket Mouse part 3 Starter Project. Unpack it and open it in Unity.

Strap yourself in, this tutorial is about to get real.

01

Creating a Sliding Menu

In many cases, you want to provide your users easy access to some game options or features, but don’t want to waste space on the screen. This is a job for a sliding menu.

You’ve seen these before: they’re a control that comprises a small, unassuming button that is always visible and a menu that slides out to reveal options. Your first step is adding that button.

Adding an Open Button

You should already know how to add a button after working through the first two parts of this series, but if not, the following directions should be ample for you to accomplish the task.

Select GameObject \ UI \ Button in the menu. Rename the newly added button to Btn_Slide and remove the nested Text object, since the button won’t need a label.

Select Btn_Slide in the Hierarchy and open the Menu folder in the Project window. Drag the btn_9slice_normal image to the Source Image field in the Inspector.

Now set the button position and size as follows:

  1. Set Anchors to bottom-left.
  2. Set both Pos X and Pos Y to 80.
  3. Set Width and Height to 64.

02

And that’s how simple it is to complete the first step.

Add the Masking Panel

To create this control, you’re going to need two panels. One will define the mask and the other will move within the mask.

Note: If you’re not entirely sure what a mask is, don’t sweat it. Just follow the steps and you’ll see how it works in real-time. You’ll need to have both panels to see it in action.

Select GameObject \ UI \ Panel to create the first panel that will be the mask. This will add a Panel to the Hierarchy. Select it and follow these steps:

  1. Rename it to Pnl_Mask.
  2. Drag it over Btn_Slide to add it as a child object.
  3. Set Anchors to top-center.
  4. Set Pivot to (0.5, 0)
  5. Set both Pos X and Pos Y to 0.
  6. Set Width to 64 and Height to 192.
  7. Add the mask component by clicking Add Component button and selecting UI \ Mask.
  8. Uncheck Show Mask Graphic inside the mask component dialog.

Screen Shot 2016-12-11 at 10.22.18 PM

Note: You don’t always have to add the panel with a mask as a child node of the button. But when you do, you ensure that when the button moves, the masking panel moves with it.

Adding the Content Panel

Add another panel by selecting GameObject \ UI \ Panel and following these steps:

  1. Rename it to Pnl_Content
  2. Add it as a child of Pnl_Mask

    Note: Did you notice that you can see only a small portion of the white panel, although its size didn’t change? After adding it as a child of the panel with a mask, you now only see the portion of pnl_content that is inside the rect of pnl_mask.

  3. Set the Anchors to stretch-stretch.
  4. Set Left, Top, Right and Bottom to 0.
  5. Set Pivot to (0.5, 1)

04

Now it’s time to change the background image for the content panel.

Open the Menu folder in the Project window and select the slide_menu_panel_9slice image. Open Sprite Editor in the Inspector and set all Border values to 8. Click Apply!

After that, select Pnl_Content in the Hierarchy, and then drag slide_menu_panel_9slice from the Project window to the Source Image field in the Inspector.

On the following GIF, you can see both how the content panel should look and how the mask component works. Now you see it, now you don’t

06

Note: As you can see, a mask works similarly to a window in a wall. If someone is walking along a wall, you can only see him when he passes by a window. Another way to think of it is as a cloaking device that allows only a portion of the image to show through.

Adding Buttons

You’re about to add three buttons to the sliding menu.

To create the first button, select GameObject \ UI \ Button. Rename it to Btn_About and remove the text child.

Drag the Btn_About button onto Pnl_Content in the Hierarchy to add it as a child. Open the Menu folder in the Project window and drag slide_menu_btn_about to the Source Image in the Inspector. Click Set Native Size.

Set Anchors to top-center and Pivot to (0.5, 1). After that, set both Pos X to 0 and Pos Y to 0.

Now it’s your turn to add two remaining buttons, all by yourself.

Name them Btn_Achievements and Btn_Leaderboards and use the slide_menu_btn_achievements and the slide_menu_btn_leaderboards images respectively.

If you need a nudge, feel free to open up the spoiler.

[spoiler title=”Adding More Buttons”]
Right-click on the Btn_About in the Hierarchy and select Duplicate. Yes, this time you’ll take the easy way. :]

Rename the duplicate to Btn_Achievements, change its Pos X to 0 its Pos Y to -64 and use the slide_menu_btn_achievements from the Menu folder in Project window as Source Image.

After that, duplicate the achievement button. Name it Btn_Leaderboards, set Pos X to 0 and Pos Y to -128 and use slide_menu_btn_leaderboards as the source image.
[/spoiler]

This is what you see in the end:

07

Making the Panel Slide Up and Down

To make the panel slide up and down, you’re going to use the same technique you’ve already employed for buttons and the settings dialog.

It will be easy, just follow these steps:

  1. Select Pnl_Content in the Hierarchy and open the Animation view.
  2. Create a new clip by clicking on the Create button.
  3. Name the animation sliding_menu_down and save it the Animations folder.

    09

  4. Click on the 1:00 mark in the timeline. This should also enable recording in the Animation view. Turn it on by pressing the red circle button, and then look for the playback controls to turn red.
  5. Set the Top to 192 in the Inspector and then stop recording.
    Inspector values
  6. Open the Animations folder in Project window and select sliding_menu_down. Uncheck Loop Time in the Inspector.

    12

  7. Select Pnl_Content in Hierarchy and open the Animator view. Copy and paste the sliding_menu_down state to create a duplicate.

    Screen Shot 2015-11-18 at 10.24.05 PM

  8. Rename the duplicate to sliding_menu_up and set its Speed to -1 in the Inspector.
  9. Screen Shot 2015-11-18 at 10.29.29 PM

  10. Create two transitions: from sliding_menu_up to sliding_menu_down and from sliding_menu_down to sliding_menu_up.

    Screen Shot 2015-11-19 at 12.09.55 AM

  11. Add a new Bool parameter named isHidden and set its default value to true.

    Screen Shot 2015-11-18 at 10.34.43 PM

  12. Select the transition from sliding_menu_up to sliding_menu_down, and in the list of conditions set isHidden to true.
  13. Screen Shot 2015-11-19 at 12.12.54 AM

  14. Select the transition from sliding_menu_down to sliding_menu_up, and this time set Conditions to be isHidden equals false.

    Screen Shot 2015-11-19 at 12.14.36 AM

  15. Next, right click in the Animator and select Create State and then choose Empty.
    Screen Shot 2015-11-19 at 12.16.10 AM (2)
  16. In the Inspector, name the state idle. Next, right click the state and choose Set as Layer Default State. Create a transition between idle to sliding_menu_up. Set the Condition as isHidden is equal to false.
    Screen Shot 2015-11-19 at 12.18.28 AM
  17. Select Pnl_Content in the Hierarchy and open the Animation View. Create a new animation clip and call it idle.
    create a new animation
  18. In the first keyframe, set the Top to be 192. Then Stop the recording.

That’s it, 16 easy steps! :] Select Save Scenes to save your work so far. Unfortunately, when you run your game, nothing happens.

Adding Code to Toggle the Menu

Now it’s time to make things move and you’ll do this in code. Open the UIManagerScript in a code editor and add following instance variable:

public Animator contentPanel;

After that, add the following method:

public void ToggleMenu() 
{
    bool isHidden = contentPanel.GetBool("isHidden");
    contentPanel.SetBool("isHidden", !isHidden);
}

This enables the animator component when you open the sliding menu and sets the correct isHidden parameter value.

Save the script and switch back to Unity. In Unity, select UIManager in the Hierarchy and drag Pnl_Content from the Hierarchy to the Content Panel field in the Inspector.

20

Now, select Btn_Slide in the Hierarchy. In the Inspector, find a list of On Click (Button) event handlers and add a new one by clicking the + button.

After that, drag UIManager from the Hierarchy to that new handler. Then, in the function selection dropdown, select UIManagerScript \ ToggleMenu ().

21

Select Save Scenes to save your work, run the scene and relish in your cool sliding-up-and-down menu.

Adding a Rotating Gear Icon

There is something missing, don’t you think? Oh, of course! The rotating gears icon on the opening button itself — the one shown in the animated GIF image at the start of this part.

Adding the Gear Image

Your first step is to add an image as a child object of btn_slide, and animate it during the menu opening and closing animations.

Choose GameObject \ UI \ Image to create a new image. Drag it over Btn_Slide in the Hierarchy to add it as a child object.

After that, follow these steps:

  1. Rename the image to Img_Gear
  2. Set the Anchors to middle-center
  3. Set both Pos X and Pos Y to 0.
  4. Open the Menu folder in Project window and drag the slide_menu_gear image to the Source Image field in the Inspector.
  5. Click Set Native Size.

22

Animating the Gear Image

By now, the technique of creating two animation states and a parameter to switch between them should be second nature. So, you should be able to create a left-rotating gear and reverse the animation to make a right-rotating gear on your own.

Here are the need-to-know details:

  • Animation duration should be identical to the sliding panel animation, and this is easy since all animations in this tutorial are exactly 1 second long.
  • The gear should rotate 360 degrees around the Z axis (Rotation Z).
  • Use the same name isHidden for parameter name and set its default value to true.
  • Remember to disable looping and the Animator component.

Should you find that you need more detailed directions, feel free to open the spoiler below.

[spoiler title=”Rotating the Gear”]
Select Img_Gear in the Hierarchy and open the Animation view. Create a new clip by clicking on the Create button and name it gear_rotate_up. Save it in the Animations folder.

Then click on the 1:00 mark in the timeline. After that, in the Inspector, change Rotation Z to 360.

Stop recording by clicking the button with a red circle.

Now open the Animations folder in the Project window and select gear_rotate_up. In the Inspector, uncheck Loop Time.

g2

Now, it’s time to set up states. Select Img_Gear in the Hierarchy, open the Animator view, and then follow these steps:

  1. Right click the Animator, and choose Create State, then choose Empty.
  2. In the Inspector, name the state gear_idle
  3. Right click gear_idle and select Set as Layer Default State.
  4. Duplicate the gear_rotate_up state by copying and pasting it.
  5. Rename the duplicate to gear_rotate_down, and change its Speed to -1 in the Inspector.
  6. Add a new Bool parameter named isHidden, and set its default value to true.
  7. Create two transitions between states. Under conditions, set isHidden to true for the transition from gear_rotate_up to gear_rotate_down, and isHidden to false for the reverse transition.
  8. Create a transition from gear_idle to gear_rotate_up. Set isHidden condition to false

[/spoiler]

Triggering the Gear Animation from Code

To complete the sliding menu control, you need to trigger the gear animation from code, but you only need to write a few lines.

Open the UIManagerScript in a code editor and add following instance variable:

public Animator gearImage;

Then scroll down and find the ToggleMenu method. Add the following to the bottom of the method’s body:

public void ToggleMenu() 
{
    //..skipped..

    gearImage.SetBool("isHidden", !isHidden);
}

This enables the Animator component and sets its isHidden parameter to the same value as the content panel’s Animator isHidden parameter.

Save the script file and switch back to Unity.

In Unity, select UIManager in the Hierarchy. Drag Img_Gear to the Gear Image field in the Inspector.

23

Save Scenes your work and run the scene and enjoy your fancy rotating gear icon.

24

Good job! The sliding menu is complete and your scene is coming together.

You’re not going to handle clicks on the buttons in the menu, because you should be already familiar with handling UI events and actually integrating Game Center would send this tutorial down a rabbit hole. Instead, you’re going to update the old GUI-based RocketMouse scene so that it uses the new GUI system.

Updating the RocketMouse Scene to use Unity’s UI

In the RocketMouse game, a few UI elements use the old GUI method to display: the points scored and the button to restart the game. You’re going to replace them with new text and image UI elements, and a dialog that allows you to restart the game or exit to the main menu.

Adding the Points Label

Switch to the RocketMouse scene and open the Scenes folder in the Project window. Double-click on the RocketMouse scene to open it.

Choose GameObject \ UI \ Text to create a new Text UI element. You’re also going to work with Canvas and EventSystem while you’re in here.

25

Select Text in the Hierarchy and make following changes in the Inspector:

  1. Rename it to Txt_Points.
  2. Set Anchors to top-left.
  3. Set Pivot to (0, 0.5).
  4. Set Pos X to 50 and Pos Y to -30.
  5. Change Text to 0, since the player starts with zero points.
  6. Open the Fonts folder in the Project window and drag TitanOne-Regular to the Font field in the Inspector.
  7. Set Font Size to 24.
  8. Set Horizontal Overflow to Overflow to make sure the label can display even the most outrageous scores.

26

Also, don’t forget to change the color of the text to be white.

Adding a Points Icon

Nowadays, simply displaying text to show the points is not enough. You need to make sure that it’s perfectly clear what this text means from the moment the player’s eyes see it.

Yes, players these days are spoiled by impressive UI on even the simplest apps, so you need to add an icon to make the score perfectly crisp, clear and well-defined.

Select GameObject \ UI \ Image to create a new Image. Select it in the Hierarchy and follow these steps:

  1. Rename it to Img_Points
  2. Drag it over Txt_Points to add it as a child, so that when you move the label the icon moves, too.
  3. Set Anchors to middle-left.
  4. Set Pivot to (1, 0.5).
  5. Set both Width and Height to 32.
  6. Set Pos X to -5 and Pos Y to 0.
  7. Open the Sprites folder in the Project window and drag the coin image to the Source Image field in the Inspector.

Note: This time you do not click Set Native Size, because you’re going to reuse the image for coins in the game, which will be a bit bigger than the icon.

Updating the Points Label

Most of the code of the game lives in the MouseController.cs script, so you’ll edit this script to update the points label. In fact, until the end of this tutorial, you’ll only work with this script.

Note: Normally, I’d break this huge script into several smaller chunks, but I don’t want you to waste your time on housekeeping, especially because refactoring will take more time and will require a strong understanding of existing code.

It’s better to work with it in a big ol’ block so you can just make the small changes needed and move on with your life.

Open the Scripts folder in the Project window and double-click on the MouseController script to open it in a code editor.

When the script loads, find and remove following methods, which use the old GUI system:

  • onGUI
  • DisplayCoinsCount
  • DisplayRestartButton

Add the following using directive:

using UnityEngine.UI;

After that, add the following instance variable to contain a reference to the label:

public Text coinsLabel;

Finally, add the following line at the end of CollectCoin(), which is called every time the mouse collects a coin.

coinsLabel.text = coins.ToString();

Save the script file and switch back to Unity.

In Unity, select mouse in the Hierarchy and drag Txt_Points to the Coins Label field in the Inspector.

27

Run the scene and send the mouse out to collect a few coins. You should see the label update when he collects a coin.

28

Everything is looking good, but you might have noticed one rather embarrassing problem. When you removed the old onGUI method you also removed the button that displayed when the mouse dies, leaving the player unable to restart the game. Doh!

Adding a Restart Dialog

I think you’ve got a good handle on the new GUI system and can create this dialog without a bunch of prodding from me. So create a panel with a label and two buttons that looks like this:

29

Place it in the center of the canvas.

30

Come back when you’re done – you’re on your own, friend!

Gotcha? :] Of course I’m not going to leave you hanging. If you’d like a step-by-step, just open up the spoiler below.

[spoiler title=”Solution”]

  1. Create a new Panel using GameObject \ UI \ Panel and rename it to Dlg_Restart.
  2. Set Anchors to middle-center.
  3. Set both Width and Height to 200 and both Pos X and Pos Y to 0.
  4. Use the settings_panel_bg_9slice image from the Menu folder as the Source Image for the panel.
  5. Double-click on the Color field in the Inspector and set A to 255 to remove transparency.
    31
  6. Create a Text element by selecting GameObject \ UI \ Text and rename it to Lbl_YouLose.
  7. Drag Lbl_YouLose over Dlg_Restart to add it as a child element.
  8. Set its Anchors to top-center, Pos X to 0 and Pos Y to -40.
  9. Use the DCC-Dreamer font from the Fonts folder. Set Font Size to 30.
  10. Set Alignment to Center Align and Horizontal Overflow to Overflow.
  11. Change Text to You Lose :[
  12. Set the text Color to completely white (no transparency).

    32

  13. Create a new Button using GameObject \ UI \ Button and rename it to Btn_Restart.
  14. Drag it over Dlg_Restart to add it as a child.
  15. Set its Anchors to top-center, Pos X to 0, Pos Y to -100.
  16. Set its Width to 135 and Height to 45.
  17. Use btn_9slice_normal as Source Image.

    34

  18. Select the nested Text element and set its Font to TitanOne-Regular, Font Size to 18 and Color to completely white (no transparency). Set the value of the Text field in the Inspector to Restart.
  19. 35

  20. To create a second button, simply right-click on Btn_Restart and select Duplicate. Name it Btn_Exit. Set its Pos Y to -160. Then select the nested text element and change its Text to Exit.

[/spoiler]

Displaying the Restart Dialog

You’re not going to animate the appearance of the dialog. Instead, you’ll just hide the dialog at the start and show it when the player loses the game.

Open the MouseController script in a code editor and add the following instance variable:

public GameObject restartDialog; 

Then add following line of code toStart() to hide the dialog at the start:

restartDialog.SetActive(false);

Scroll down and add following line to the end of HitByLaser():

restartDialog.SetActive(true);

As you probably guessed, HitByLaser() is called when the mouse dies. Hence, it’s the perfect place to display a restart dialog.

Add the following two methods to restart and exit the game:

public void RestartGame() 
{
    Application.LoadLevel (Application.loadedLevelName);
}
    
public void ExitToMenu() 
{
    Application.LoadLevel ("MenuScene");
}

You’ll link them to the corresponding buttons in a moment.

Save the script file and switch back to Unity.

In Unity, select Mouse in the Hierarchy and drag Dlg_Restart to the Restart Dialog field in the Inspector.

36

Then select Btn_Restart in the Hierarchy and scroll down to the On Click (Button) list.

Click + to add a new item. After that, drag Mouse from the Hierarchy to the new item. In the function selection dropdown, select MouseController \ RestartGame ().

37

Now, select Btn_Exit, and repeat the process, but this time select the MouseController \ ExitToMenu () function.

Save the scene to save your work then run the scene and send your mouse into the laser’s line of fire. You should see a dialog appear instantly after he dies. If you press Restart, you’ll restart the game. If you press Exit you’ll return to the main menu.

38

And once again I’m ending a tutorial on a high note — with an image of the poor, lifeless mouse. Sorry, no kittens today, maybe in the next series. :]

Where To Go From Here?

Congratulations on completing this tutorial! You can download the final project here: Rocket Mouse Starter Project

I hope you like the UI system and are excited to create some cool user interfaces in your games! Surely, the prospect of minimal coding alone should have you feeling a bit gleeful.

If you create some awesome control using the UI system, we’d all love to see your handiwork. Go ahead and post a screenshot, video or GIF animation in comments to show the world your awesome new skills — and maybe inspire a fellow dev or few (or make them jealous). :]

If you have any questions or comments, please leave them below. I will be happy to answer!

Good luck!

Average Rating

5/5

Add a rating for this content

1 rating

Contributors

Comments