Update 11/20/15: This tutorial was updated to Unity 5.2 by Pedro Pereira & Orlando Pereira. Original post by tutorial team member Kirill Muzykov.
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
To start, simply open 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 final project for Part 2 here: RocketMouse_UI_Part2_Final. Unpack it and open it in Unity.
Strap yourself in, this tutorial is about to get real.
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 Browser. Drag the btn_9slice_normal image to the Source Image field in the Inspector.
Now set the button position and size as follows:
- Set Anchors to bottom-left.
- Set both Pos X and Pos Y to 80.
- Set Width and Height to 64.
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:
- Rename it to Pnl_Mask.
- Drag it over Btn_Slide to add it as a child object.
- Set Anchors to top-center.
- Set Pivot to (0.5, 0)
- Set both Pos X and Pos Y to 0.
- Set Width to 64 and Height to 192.
- Add the mask component by clicking Add Component button and selecting UI\Mask.
- Uncheck Show Mask Graphic inside the mask component dialog.
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:
- Rename it to Pnl_Content
- 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.
- Set the Anchors to stretch-stretch.
- Set Left, Top, Right and Bottom to 0.
- Set Pivot to (0.5, 1)
Now it’s time to change the background image for the content panel.
Open the Menu folder in the Project Browser 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 Browser 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
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 Browser 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.
This is what you see in the end:
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:
- Select Pnl_Content in the Hierarchy and open the Animation view.
- Create a new clip by clicking on the Create button.
- Name the animation sliding_menu_down and save it the Animations folder.
- 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.
- Set the Top to 192 in the Inspector and then stop recording.
- Open the Animations folder in Project Browser and select sliding_menu_down. Uncheck Loop Time in the Inspector.
- Select Pnl_Content in Hierarchy and open the Animator view. Copy and paste the sliding_menu_down state to create a duplicate.
- Rename the duplicate to sliding_menu_up and set its Speed to -1 in the Inspector.
- Create two transitions: from sliding_menu_up to sliding_menu_down and from sliding_menu_down to sliding_menu_up.
- Add a new Bool parameter named isHidden and set its default value to true.
- Select the transition from sliding_menu_up to sliding_menu_down, and in the list of conditions set isHidden to true.
- Select the transition from sliding_menu_down to sliding_menu_up, and this time set Conditions to be isHidden equals false.
- Next, right click in the Animator and select Create State and then choose Empty.
- In the Inspector, name the state idle. Next, right click the state and choose Set Layer as Default State. Create a transition between
idle
tosliding_menu_up
. Set the Condition as isHidden is equal to false.
- Select
Pnl_Content
in the Hierarchy and open the Animation View. Create a new animation clip and call it idle. - In the first keyframe, set the Top to be 192.
That’s it, 17 easy steps! :] Unfortunately, when you run your game, nothing happen.
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 MonoDevelop 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.
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 ().
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:
- Rename the image to Img_Gear
- Set the Anchors to middle-center
- Set both Pos X and Pos Y to 0.
- Open the Menu folder in Project Browser and drag the slide_menu_gear image to the Source Image field in the Inspector.
- Click Set Native Size.
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.
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 MonoDevelop 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.
Run the scene and enjoy your fancy rotating gear icon.
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 Browser. 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.
Select Text in the Hierarchy and make following changes in the Inspector:
- Rename it to Txt_Points.
- Set Anchors to top-left.
- Set Pivot to (0, 0.5).
- Set Pos X to 50 and Pos Y to -30.
- Change Text to 0, since the player starts with zero points.
- Open the Fonts folder in the Project Browser and drag TitanOne-Regular to the Font field in the Inspector.
- Set Font Size to 24.
- Set Horizontal Overflow to Overflow to make sure the label can display even the most outrageous scores.
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:
- Rename it to Img_Points
- Drag it over Txt_Points to add it as a child, so that when you move the label the icon moves, too.
- Set Anchors to middle-left.
- Set Pivot to (1, 0.5).
- Set both Width and Height to 32.
- Set Pos X to -5 and Pos Y to 0.
- Open the Sprites folder in the Project Browser 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 Browser and double-click on the MouseController script to open it in MonoDevelop.
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.
Run the scene and send the mouse out to collect a few coins. You should see the label update when he collects a coin.
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:
Place it in the center of the canvas.
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.
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 MonoDevelop and add the following instance variable:
public GameObject restartDialog; |
Then add following line of code in the Start
method to hide the dialog at the start:
restartDialog.SetActive(false); |
Scroll down and add following line to the end of the HitByLaser
method:
restartDialog.SetActive(true); |
As you probably guessed, the HitByLaser
method 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.
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 ().
Now, select Btn_Exit, and repeat the process, but this time select the MouseController\ExitToMenu () function.
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.
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: RocketMouse Final.
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!
The post Introduction to Unity UI – Part 3 appeared first on Ray Wenderlich.