Getting Started
In this tutorial, you’ll spruce up the scene by adding animations, a settings dialog and more UI controls like the slider and the toggle. If you don’t have the project already, download it here.
So, go ahead and open the project in Unity. Open the MenuScene, grab an invigorating beverage and start thinking GUI!
Animating Buttons
You’re going to jump right into the exercises by adding some cool animations. There are several reasons for that. First — animations are cool! Second, they’re practical for this porject. You need the buttons to exit from the scene so there’s space to display the new dialog that you’ll create later.
Creating Animation and Animator
Animating buttons is no different from animating any other Unity object. You’ll need to add an Animator component, create few animations and set up states and transitions between them.
Here are the steps to success:
- Select btn_start in the hierarchy
- Open the Animation view.
- Click [Create New Clip] in the Animations dropdown list on the left.
- Name the animation btn_start_slide_out and save it in the Animations folder.
Note: Select btn_start in the Hierarchy, since you’ll add the new animation and animator to the currently selected object.
In addition to creating the animation itself, Unity also kindly adds an animator component to btn_start
and creates an Animator Controller.
Note: If you’re unfamiliar with animations and Animator Controllers in Unity, please complete the original tutorial – How to Make a Game Like Jetpack Joyride in Unity 2D.
Animating a Button Sliding Out of the Screen
Although you’ll technically make two animations — the button slide out and then the slide back in — you’re going to be a savvy developer and create one, and then reverse it.
To create the slide-out animation, follow these steps:
- Select btn_start in the hierarchy
- Make sure the Animation view is visible.
- Click on the 1:00 mark in the timeline and make sure animation recording turns on. It should do this automatically.
- Change Anchors to top-stretch.
- Change Pos Y to 60 in the Inspector.
- Stop the recording by clicking the red circle button.
Note: The easiest way to make sure recording is on is to take a look at playback controls and watch for them to turn red.
Note two following points marked with letters on the screenshot:
A: A keyframe was inserted automatically at 0:00 mark. At this point, the button is at its starting position, precisely where you positioned it in the previous tutorial.
B: Although the anchors’ visual representation didn’t turn red, you can see the numeric values changed and turned red, indicating that you’ve also animated the anchors.
Make both the animation and Scene view visible and play the animation. You’ll see something like this:
Did you notice the animation on the anchors? If not, surely you noticed that annoying blinking red arrow. (By the way, sorry about that. Graphic design isn’t my forte. Maybe I should have asked Vicki at Game Art Guppy for help.)
Anyways, why do you need to reposition anchors?
Well, when you think about it this way, it’ll be obvious: the position of the button is a distance to anchors. In case of btn_start
, it was the distance from the bottom edge. Right now, you’re only working with vertical movement, so only the bottom edge matters.
To make sure the button “leaves” the screen, you move it up until it’s no longer visible. What do you do if you don’t know the height of the screen? How do you make sure the button stops right after it’s no longer visible?
The answer is by changing its anchors.
If you set anchors to the top edge of the screen, you simply set distance from the top edge of the screen. Thus, the button will always be above the edge and independent from the height of the screen, since it’s positioned relative to the screen’s top edge.
Animating Button Slide In
Nice work! You have a button that slides out of the screen, and now you need a reverse animation. You’ll use it in two cases:
- When the scene loads, you want the button to slide into position instead of simply appearing.
- When you close the settings dialog, the buttons should return to their initial positions
It’s quite easy to do. First, you need to disable looping of the animation, since the button should move up/down and plant instead moving back and forth like a ping-pong ball.
To disable looping, open the Animations folder in the project browser and select btn_start_slide_out animation. In the Inspector, uncheck Loop Time.
Then select btn_start in the hierarchy and open the Animator view. Right-click on the btn_start_slide_out state and select Copy.
Then right-click somewhere on the free space inside the Animator view, and select Paste. This duplicates the btn_start_slide_out
state.
Now, select this duplicated state, likely called something like btn_start_slide_out 0
, and rename it to btn_start_slide_in in the Inspector. Additionally, set Speed to -1.
Then, inside the Animator view, right-click on the btn_start_slide_in and select Set As Default, since you want the button to start its lifecycle by sliding into the screen and not vice-versa.
Next, you need a parameter to control the state of the button. Click the + button and add new Bool parameter named isHidden.
Finally, add two transitions between states. To do this, right-click on the btn_start_slide_out state and select Make Transition. Then click on the btn_start_slide_in to make a transition.
After that, create a reverse transition by right-clicking btn_start_slide_in, selecting Make Transition and then clicking on the btn_start_slide_out. This is what you should get in the end:
You’re close, but you don’t want your transitions to be unconditional. Instead, you should use the isHidden parameter.
Select transition from btn_start_slide_out
to btn_start_slide_in
and change Conditions in the Inspector so that isHidden
equals false.
Then select the transition that goes in opposite direction, from btn_start_slide_in
to btn_start_slide_out
and set its Conditions to be isHidden
equals true.
Run the scene. You should see your button sleekly sliding in. Then change isHidden
manually to make the button slide back.
Note: Occasionally, I’ve encountered problems during testing when manually switching isHidden
— the button jumped to its start/stop position. However, everything worked perfectly fine when I changed the parameter within the code.
So if you’re experiencing problems, there’s no need to pound your fist on the desk. Just wait until you add the required code, which you’ll do soon.
Animating Settings Button
The settings button should slide down the screen to make some space in the center for the dialog.
Do you think you can animate the settings button yourself? All you need to know that
- Offscreen Pos Y should be -50
- You don’t need to change Anchors, since the button is already positioned relative to the bottom edge of the screen.
Give it a try on your own. If you need a nudge, feel free to sneak a peek into the spoiler below.
This is what you should get in the end:
Well, it’s nice to see the Settings button going up and down, but shouldn’t both buttons slide out simultaneously, just as they slide in at the start?
Of course they should, and you’re going to make that happen next.
Triggering Buttons Animation from the Script
In MonoDevelop, open the UIManagerScript
that you created in Part One, and add the following instance variables just inside the class definition:
public Animator startButton; public Animator settingsButton; |
After that, add following method:
public void OpenSettings() { startButton.SetBool("isHidden", true); settingsButton.SetBool("isHidden", true); } |
That is the all code you need. Save the script and switch back to Unity.
In Unity, select UIManager
in the Hierarchy. Drag btn_start from the hierarchy to the Start Button field in the Inspector and btn_settings to the Settings Button field.
Then select btn_settings in the hierarchy and click + in the On Click (Button) list. Drag UIManager from the hierarchy to the new item in the list. After that, open the function selection menu and select UIManagerScript\OpenSettings ().
Run the scene. Wait for the buttons to stop moving and click on the Settings button. You should see both buttons move out of the screen in opposite directions simultaneously.
Adding the Settings Dialog
Look at all that gorgeous free space you created! That seems like the perfect place for a dialog to slide in there and fill the empty space. After all, nature abhors a vacuum :]
Creating the Panel
Usually, dialogs contain some other controls that should appear and move with dialog. Hence, it’s effective to create the dialog as a panel and set other UI Elements as child objects.
To create a panel, select GameObject\Create UI\Panel in the menu. This will create a full-screen panel that uses a white, semi-transparent image as a background. So, you should see some kind of full-screen veil.
However, this dialog won’t be full-screen; in fact, it will be relatively small. Follow these steps to set the dialog’s size and position:
- Select Panel in hierarchy and rename it to
dlg_settings
. - Set its Anchors to middle-right, since you’ll position the dialog to the right edge off the screen, so that it’s not visible when you run the scene.
- Set Width to 400 and Height to 150.
- Set Pos X to 220 and Pos Y to 0.
You should see a semi-transparent rectangle to the right of the canvas rectangle. All UI elements outside this rectangle are not visible on the screen. This is precisely what you want for the dialog!
Setting the Dialog’s Background Image
You’re going to use a 9-slice image as the dialog’s background, so you need to set the border in the Import Settings first.
Open the Menu folder in the project browser and select settings_panel_bg_9slice. In the Inspector, click Sprite Editor to open the Sprite Editor view.
Set all Border values to 20 and click Apply at the top.
Now you can use this image as dialog background.
Select dlg_settings in the hierarchy and drag settings_panel_bg_9slice to the Source Image field in the Inspector. Double-click on Color right next to the Source Image field, and set A to 255 to remove transparency.
This is how the dialog should look like after you set the background image:
Adding the Label
In its present state, it’s difficult to argue that green rectangle is a settings dialog, but there’s an easy way to fix this — all you need to do is to write “Settings” on it. Poof! Whoosh! Magic. :]
Select GameObject\Create UI\Text to create a new Text UI element. Select Text in the hierarchy and rename it to lbl_settings. Then drag lbl_settings over dlg_settings to add it as a child object.
After that, select lbl_settings in the hierarchy and make following changes:
- Set Anchors to top-center.
- Set Pos X to 0 and Pos Y to -40.
- Change Text to Settings.
- Open the Fonts folder in the project browser and drag DCC – Dreamer font to the Font field in the Inspector.
- Set Font Size to 30.
- Set Alignment to Center Align.
- Set Color to White, with A (Alpha) 255 to remove transparency.
Animating the Settings Dialog
Now you’ve got a legitimate Settings dialog, and the next step is to make it appear when the user clicks the Settings button.
You’re going to use almost exactly the same technique as you did to make the buttons slide in and out, the only difference being that the dialog won’t slide in automatically after the scene starts.
Select dlg_settings in the hierarchy and open the Animation view. Then create a new animation by clicking [Create New Clip] in the animations list dropdown.
Name the animation dlg_settings_slide_in and save it in the Animations folder.
Then click on the 1:00 mark in the timeline and make sure recording is started, or start it manually by clicking the record button.
In the Inspector, set Anchors to middle-center and Pos X to 0.
Stop recording the animation.
Open the Animations folder in the Project browser and select dlg_settings_slide_in. In the Inspector uncheck Loop Time.
Now, switch to the Animator view. Copy and paste the dlg_settings_slide_in state to duplicate it. Rename the duplicate to dlg_settings_slide_out, and set its Speed to -1.
Note: This time, don’t change the default state! Dialog’s default state should stay dlg_settings_slide_in
.
Click the + button and add new Bool parameter named isHidden.
Create two transitions between states, just as you did for the buttons. Then add isHidden parameter of type Bool.
Change the conditions of the dlg_settings_slide_out => dlg_settings_slide_in transition to be isHidden equals false, and for the dlg_settings_slide_in => dlg_settings_slide_out transition to be isHidden equals true.
Run the scene now and you’ll see the dialog sliding in at the start, and then overlapping the buttons.
This is getting there, but still not what you want. You need to disable the Animator component so it won’t play the animation at the start.
Select dlg_settings in the hierarchy and disable the Animator component.
Displaying Dialog on Button Click
When you run the scene, the dialog doesn’t appear straight away. This is good — however, it won’t show up even when you click the settings button. This — is not good.
My friend, you’re looking at your next problem to solve.
Open the UIManagerScript
in MonoDevelop and add following instance variable:
public Animator dialog; |
Then add following code to the end of OpenSettings
:
public void OpenSettings() { //..skipped.. dialog.enabled = true; dialog.SetBool("isHidden", false); } |
This enables the Animator component and sets the correct value to the isHidden
parameter.
Finally add new method called CloseSettings
as follows:
public void CloseSettings() { startButton.SetBool("isHidden", false); settingsButton.SetBool("isHidden", false); dialog.SetBool("isHidden", true); } |
This returns the buttons and hides the dialog. You’ll add the UI element that calls this method in a moment.
Save the UIManagerScript
and switch back to Unity.
Select UIManager in the hierarchy and drag dlg_settings to the Dialog field in the Inspector.
Run the scene, then click the Settings button and see how the buttons slide out as the dialog slides in.
That’s better, but you can’t close the dialog.
To fix this, you need to add some kind of close button to the dialog.
Adding the Close Button
Select GameObject\Create UI\Button to create a button. Rename this new button to btn_close and drag it over dlg_settings in the hierarchy to add it as a child object. Also, this button won’t have a text on it, so remove the text nested in btn_close
.
This is what you should have in the hierarchy at this point:
Now select btn_close and follow these steps:
- Set Anchors to top-right.
- Set both Pos X and Pos Y to 0.
- Open the Menu folder in the Project browser and drag settings_btn_close to Source Image field in the Inspector.
- Click Set Native Size.
This is how the dialog should look in the Scene view now:
Note: This time, you’re going to use another method to highlight the button’s image (Transition property in the Button script) called ColorTint, which is the default transition type. You’ll do this instead of adding two more images to represent highlighted and pressed button states.
The button looks great, but it does nothing. Fortunately, you’ve already added the method this button needs to call.
Select btn_close in the hierarchy, scroll down to the On Click (Button) list and click +. Drag UIManager from the hierarchy to the new item and then select UIManagerScript\CloseSettings () method in the dropdown.
Run the scene. Click the Settings button and close the scene by clicking Close after the dialog slides into the scene.
Hey, you’ve done well. That looks nice! :]
Adding Sound Settings
There’s not much sense in keeping a meaningless settings dialog, so, it’s time to add some actual settings to it. In this dialog, the player will have control over the music’s volume in the menu scene.
Music? Yes, what fun is a game without a rockin’ soundtrack?
Adding Music to the Menu Scene
You’re welcome to rummage around your files for a suitable clip, but you don’t have to because the project already contains a snappy music track. All you need to do is to play it.
Select Main Camera in the hierarchy and add the Audio Source component. Then, in the project browser, open the Audio folder and drag music to the Audio Clip field in the Inspector.
Enable Play On Awake.
Toggling Music On and Off
To toggle music on and off you’re going to use a…wait for it…toggle control. Select GameObect\Create UI\Toggle to add a toggle UI element to the scene.
The toggle controls consist of the root object which has a Toggle script attached, and several child objects:
- Background: Image that is always visible (i.e. in both On and Off states)
- Checkmark: Image that is only visible when toggle is active (ON).
- Label: A label displayed next to toggle.
You don’t need a label this time, so remove the nested Label. Then rename toggle to tgl_sound and drag it over dlg_settings to put it inside the dialog. This is what you should see in the hierarchy after you’re done:
Select tgl_sound in the hierarchy. Set its Anchors to middle-left, Pos X to 115 and Pos Y to -10.
Note: Remember how anchors and position are set relative to the parent? This is why it’s important to add tgl_sound
as a child of dlg_settings
first and only after that set its position.
Keep in mind, changing anchors and pivot won’t change the UI element position, instead, they update position fields (e.g. Pos X, Pos Y, Left, Right) to values that position the element at the same place by using new anchors and pivot. Set these first, and play with the them to set the correct position.
Also, under the Toggle (Script) component, uncheck the Active checkbox.
Now you need to set images for Background and Checkmark child objects. Just as you’ve done with the other images, take them from the Menu folder in the project browser, and open that folder in the project browser.
You’re going to need two images:
- settings_btn_sound for Background
- settings_btn_sound_checkmark for Checkmark
Select Background contained in tgl_sound
in the hierarchy and drag settings_btn_sound from the project browser to Source Image in the Inspector. Then click Set Native Size.
Then select Checkmark and repeat the previous steps, but this time use the settings_btn_sound_checkmark image from the project browser.
This is what you should see in the Scene View:
Note: As you can see, the size of the root object (wide rectangle) doesn’t match the background images. You can adjust its size, but it just fine this way.
Muting the Music
The good thing about UI elements’ event handlers is that sometimes you can get away without writing any code at all. Instead, you can set the UI element to change the property or directly call a function of the component attached to the object.
Here’s how you can change the mute property of the Audio Source component attached to MainCamera.
Select tgl_sound in the hierarchy, and in the Inspector find On Value Changed (Boolean) list. Click + to add new item.
Drag MainCamera from the hierarchy to the newly added item. Open the function selection dropdown and select AudioSource\mute from the Dynamic bool section at the top.
Note: When you look closely at the function selection options, you’ll see two mute properties: one in the Dynamic bool section and the other in Static Parameters.
The difference is quite trivial. If you select mute in the Dynamic bool section, its value will be set to the current value of the toggle’s Active property each time you toggle it.
If you select the mute property from the Static Parameters section, the new input field will appear and you’ll able to set its value in the Inspector to some constant value.
Of course, in the Dynamic bool section there are only properties and methods that take Bool values, because toggle’s active property type is Bool. Since you can specify any value as the static parameter, the Static Parameters section contains all public properties and methods.
Hence, when toggle is active (e.g. active equals true) it sets mute property of AudioSource to true and mutes the music.
Run the scene, open the settings dialog and try switching music ON and OFF.
Using Slider to Regulate the Volume
It’s really cool that toggle can synchronize its ON and OFF states with some other component’s field, but what if you have a range of values? In this case, you can use the Slider UI element.
Select GameObject\Create UI\Slider to add a slider. Rename it to sdr_volume and put it inside dlg_settings.
Select sdr_volume in the hierarchy and set its Anchors to middle-right. Then set its Pivot to (1, 0.5) so that you could position it using the middle point of its right edge.
Finally set its Pos X to -20, Pos Y to -10, Width to 270 and Height to 35.
This is how the Settings dialog should look right now:
If you take a look at the hierarchy, you’ll see the slider control has more parts than a toggle or button. Here are the main parts:
- Background: Image that shows the bounds of the slider and its inner area when it’s not filled (i.e. when handle is all the way to the left).
- Handle: Image for the handle. You drag it to change the slider’s value.
- Fill: Image that stretches to show the value of the slider.
In fact, the fill image is not the only part that can stretch, so normally it’s better to use 9-scale images for all three parts. And you have such images! Lucky you! :]
Open the Menu folder in the project browser and find three images corresponding to each part of the slider: slider_background, slider_fill and slider_handle.
For each image, open the Sprite Editor in the Inspector and set all values for Border to 8. Click Apply.
Now you need to set the corresponding image for each part of the slider:
- Select sdr_volume and drag slider_background to Source Image in the Inspector.
- Select Fill (not Fill Area) and drag slider_fill to Source Image.
- Select Handle and drag slider_handle to Source image.
If you run the scene now and open the Settings dialog, you should see something like this:
Changing the Volume of the AudioSource Component
Changing the music volume using the slider is similar to what you did with toggle.
Select sdr_volume in the hierarchy. In the Inspector, scroll down to see On Value Changed (Single) list and click + to add new item.
Drag MainCamera from the hierarchy to that new item in the list, open the function selection dropdown and select AudioSource\volume in the Dynamic float section.
Run the scene, open the Settings dialog and change the slider’s value. You should hear the volume go up and down as you drag the slider handle. Personally, I find it to be a super-awesome feature. :]
Where To Go From Here?
Just as I promised in the end of Part 1, in this part you’ve added more controls, learned how to animate them and made a fully functioning menu scene. While it’s fairly simple, you’ve explored most of the UI controls.
If you’d like to see it in its final, perfect form, download it here: Rocket Mouse Part Two Final Project
In Part 3, the final part, you’re going to learn advanced techniques, including using the mask component to create a sliding menu. Also, you’ll create more animations and learn how to migrate legacy GUI code to the new UI.
If you have any questions, comments or discoveries to share, please feel free to join the conversation below.
Unity 4.6: New GUI – Part 2 is a post from: Ray Wenderlich
The post Unity 4.6: New GUI – Part 2 appeared first on Ray Wenderlich.