So far in our efforts to create an animated pause menu, we have set up the required UI elements for the menu, and created the animation clip that will drive the transition between the paused and unpaused states of the game. Now, we’re going to move ahead and set up the Animator Controller that will actually handle the user’s request to pause or unpause.
In our Unity3D project, click the Canvas gameObject in the inspector, then open the Animator window (as far as I know, there is no hotkey for this, but you can find it in
Window menu under the
Animator label). You should see a fresh animator editor with three states:
Pause (or whatever you called the pause animation that we created in step 2), with a transition from
Any State doesn’t concern us in this tutorial, and
Entry just indicates which state the animator controller will immediately transition to upon starting. This is currently
Pause, but we’d like to start the game in an unpaused state, so go ahead and right click on the editing surface and select
Create State > Empty, then right click on the new state (imaginatively called “New State”) and select
Set as Layer Default State. In the inspector, go ahead and call this state
Now we need to create a transition, which is a set of conditions under which the animator controller will move from one state to another. In this case, our transition conditions are very simple: if the game is paused, we transition to the “Paused” state. To define this, we will create a new state machine parameter.
State Machine Parameters
State machine parameters are simply pieces of data that inform the animator controller about the condition of the game. They can take the form of floats, integers, booleans, or triggers (which are just a special case of boolean that resets immediately after being consumed by the state machine), and they are used in transition conditions to determine how the state machine should behave next. What makes them so powerful is that they can be set from code, which we’ll explore in the next segment of this tutorial.
In the case of the pause menu, we will drive it with a single boolean parameter:
isPaused. To create this, select the
Parameters tab on the left of the animator window, click the
+ icon, and select
Bool. Name it
isPaused and hit enter. You can leave it unchecked (the default).
State Machine Transitions
For our new parameter to be useful, we need to create some transitions that use it. As I mentioned above, a transition is a set of conditions that govern when the state machine moves from one state to another. These conditions can be timing-based (“wait for the end of this animation,” for example), or they can be condition-based.
We’ve already discussed one example of a condition:
isPaused = true. Create this transition by right clicking on the
Unpaused state, clicking
Make Transition, then click on the
Paused state. The transition is indicated by a white arrow pointing
Unpaused -> Paused. Click on the transition arrow to select it, then in the inspector, uncheck
Has Exit Time. This indicates that we don’t want to wait to transition: when the
isPaused condition (which we will set up next) becomes true, the state machine should transition immediately from
Unpaused -> Paused. In the Conditions list, click the
+ icon. Since
isPaused is our only parameter, it will be selected by default, but if you had multiple, you could find it in the “key” dropdown on the left. Make sure the “value” dropdown is set to
true, and we’re done setting up this transition.
You can test our progress so far by entering play mode, selecting the Canvas game object, and clicking the
isPaused checkbox in the parameters list. You should see the pause menu animate in (if it’s animating in over and over again, you may have forgotten to uncheck the
Loop Time box in the animator clip inspector), and if you uncheck the
isPaused parameter checkbox, you should see… nothing. The pause menu will sit there, smugly defiant. This is because we’ve told the animator controller how to animate from Unpaused to Paused, but we haven’t yet specified how it should transition back to Unpaused when the player unpauses the game.
If we wanted to make the menu disappear instantly, we could just set up a transition from
Paused -> Unpaused, give it a condition of
isPaused = false, and be done with it. For completeness’s sake, let’s say that we want to play the same animation that we play when we’re pausing, but in reverse. To do this, we need to create a third state, which we’ll call
Unpausing. Set a transition from
Paused -> Unpausing (while you’re at it, you can create a transition from
Unpausing -> Unpaused, which we’ll set up shortly), remembering to uncheck the
Has Exit Time checkbox, then give it a condition of
false. Click on the
Unpausing state node, and drag our pause animation into the
Motion property slot of the inspector. This will indicate that we want to use the same animation. To specify that we want that animation reversed, change the
Speed property from
-1. Specifying a negative speed essentially means that we start at the end of the animation clip, and work our way forward, effectively performing all the motion encoded in the animation backward.
The last thing we have to do is to configure the transition
Unpausing -> Unpaused. Remember how we discussed that one of the types of transitions is based on timing? That’s exactly what we want. The
Unpausing state starts playing our transition animation. As soon as that’s done, we want to leave the
Unpausing state and transition back to the
Unpaused state. Click on the transition arrow pointing from Unpausing to Unpaused, and open the
Settings flyout. Set
Exit Time to
Transition Duration to
0. Leave the
Conditions list empty.
Go ahead and test it out in play mode, checking and unchecking the
isPaused parameter to see the menu slide in and out smoothly. One thing I notice, though, that the exit animation (which is again just our enter animation played backward) seems to take a little too long: when I’m leaving the pause menu, I want to get back into the action quickly! Click the
Unpausing state and change the speed multiplier from
-2. Not only does this indicate that we want to play the animation in reverse of how it was recorded, we also want to play it at double speed. You can drive this value with a parameter, which opens up all sorts of possibilities, but that will be a subject for another lesson.
That’s it! You’re done setting up the animator controller! In the next installment, we’ll talk about how to drive the animator from code so that we can actually pause and unpause the game. Stay tuned!