Welcome back to our Unity 4.3 2D Tutorial series!
In the first part of the series, you started making a fun game called Zombie Conga, learning the basics of Unity’s 4.3′s built-in 2D support along the way.
In the second part of the series, you learned how to animate the zombie and the cat using Unity’s powerful built-in animation system.
In this third part of the series, you’ll get more practice creating Animation Clips, and you’ll learn how to control the playback of and transition between those clips.
This tutorial picks up where the previous part ended. If you don’t already have the project from that tutorial, download it here.
Just like you did in Part 1, unzip the file and open your scene by double-clicking ZombieConga/Assets/Scenes/CongaScene.unity.
It’s time to make that cat dance!
Getting Started
So far you’ve only been working with Animation Clips, such as ZombieWalk and CatSpawn. You learned in Part 1 that Unity uses an Animator component attached to your GameObjects in order to play these clips, but how does the Animator know which clip to play?
To find out, select cat in the Hierarchy and look at its Animator component in the Inspector. The Controller field is set to an object named cat, as shown below:
This object is an Animator Controller that Unity created for you when you made the cat’s first Animation Clip, and it’s what the Animator uses to decide which animation to play.
As you can see in the following image, the Animations folder in the Project browser contains the controller named cat, as well as a controller named zombie, which Unity created for the zombie GameObject:
Open the Animator view by choosing Window\Animator. Don’t let the similar names fool you: this view is different from the Animation view you’ve been using.
Select cat in the Hierarchy to view its Animator Controller in the Animator view, as shown below:
For now, ignore the areas named Layers and Parameters in the upper and lower left corners, respectively. Instead, take a look at the various rectangles filling most of the view.
What you’re looking at are the states of a state machine that determines which Animation Clip should run on the cat.
If you’ve never heard of a state machine, think of it as a set of possible modes or conditions, called states. At any given time, the machine is in one of these known states, and it includes rules to determine when to transition between its states.
These rectangles each represent an Animation Clip, except for the teal one named Any State, which you’ll read about later.
The orange rectangle represents the default state, i.e. the state that runs when the Animator Controller starts, as shown below:
Unity sets as the default state the first Animation Clip you associate with that Animation Controller. Because you created the cat’s clips in order, Unity correctly set CatSpawn as the default animation. However, if you ever want to assign a different default state, simply right-click the new state in the Animator view and choose Set As Default from the popup menu that appears.
The following image shows how you would manually set CatSpawn as the default state:
With the Animator view still visible, play your scene. Notice that a blue progress bar appears at the bottom of the CatSpawn state. This bar shows you the cat’s exact position within the state machine on any given frame.
As you can see, the cat is continuously running through the CatSpawn animation without ever moving on to the next state.
Note: If you don’t see this blue bar, make sure that you still have the cat selected in the Hierarchy view.
You need to provide the Animator Controller with rules for moving between states, so this is the perfect time to segue into a talk about transitions!
Transitions
A state machine isn’t very useful if it can’t ever change states. Here you’ll set up your Animator Controller to smoothly transition your cat from its spawn animation into the animation defined by CatWiggle.
Inside the Animator window, right click on CatSpawn and choose Make Transition. Now as you move your mouse cursor within the Animator view, it remains connected to the CatSpawn state by a line with an arrow in its middle. Click CatWiggle to connect these two states with a transition, as demonstrated below:
Play your scene and you’ll see the cat pop in and start wiggling. How easy was that?
That was certainly quick to set up, and you might be happy with the results. However, sometimes you’ll want to tweak a state transition. For example, in this case, there is actually something a bit strange and unintended happening, so it’s a good time to learn about editing transitions.
Editing Transitions
With only one transition defined, the easiest way to edit it is to click directly on the transition line within the Animator view, shown in the following image:
This displays the transition’s properties in the Inspector, as shown below:
When you have multiple transitions, selecting them in the Animator view isn’t always easy. Instead, you can view a specific transition’s properties by selecting the state in the Animator view that starts the transition – in this case, CatSpawn. In the Inspector, click on the appropriate row in the Transitions list to reveal details about that transition, as shown below:
In the Inspector, Unity provides you with a visual representation of how it intends to move between the two animation clips. The following image highlights the most important elements of the transition editor:
- Start and End markers: These icons specify where the transition begins and ends. They look like >| and |<, respectively.
- A blue highlighted area clearly showing the areas of the clips involved during the transition.
- A scrubber that shows your current position when previewing transitions inside the Preview pane at the bottom of the Inspector (not shown).
- Bars showing the clips involved in the transition. If one of the clips loops, it will appear multiple times if necessary to span the transition’s duration. The blue highlighted area of the bars shows what part of and to what extent each of the two clips will affect the final animation at any point in time.
- I’m not clear as to what this actually shows. It appears to be a graph displaying how the clips influence the resulting curve value, but I’m not sure. In any case, I’ve always ignored it without any problems.
As you can see in the previous image, Unity claims it will start the transition between the two clips as soon as CatSpawn starts playing. For the duration of CatSpawn‘s animation, Unity gradually blends the amount by which each clip affects the resulting animation, starting at 100% CatSpawn and 0% CatWiggle, and moving to 100% CatWiggle and 0% CatSpawn.
Unfortunately, it seems that Unity actually triggers this transition after CatSpawn has played through one full time, and then it starts the transition at the beginning of the second run of CatSpawn. You can see it more clearly in this frame-by-frame walk through of the transition:
It seems that starting the transition at the zero percent mark of the first clip causes a problem. I don’t know if this is intended behavior or a bug in Unity, but it’s a good chance to try the transition editor.
With the transition selected, look at the Conditions list in the Inspector, shown below (you might have to scroll down a bit to see it):
This list contains the conditions that trigger this transition. By default, the only condition available is named Exit Time, which is considered true
after a specified percentage of the first animation has played.
Exit Time’s value is currently 0.00, meaning it’s set to the start of the clip. You can adjust this value directly in the field next to Exit Time or you can move the Start Marker (>|) described earlier, but it’s easier to be accurate using the field directly.
Change the value for Exit Time to 0.01, as shown in the following image. Exit Time’s value is based on a zero to one scale, so 0.01 means to start the transition after playing just one percent of CatSpawn.
Play your scene again and the cat animates into view, transitioning smoothly into its wiggle animation.
Take a look at the transition in slow motion to see the difference more clearly:
With all this jumping around the cat’s doing, the zombie is sure to notice it! Of course, getting attention from zombies in real life usually leads to zombification, and in this game it’s no different. When the zombie touches them, the cats will turn into demon zombie conga cats. To indicate their undeath, you’ll turn them green.
Animating a Color
Switch to CatZombify in the Animation view and add a curve to edit the Sprite Renderer’s color.
When you add a new curve, Unity automatically adds keyframes at frames zero and 60. You can move between them like you’ve been doing so far, either using the frame field in the Animation view’s control bar, by selecting a keyframe within the timeline, or by dragging the scrubber to a specific frame. However, the Animation view’s control bar also includes two buttons for moving to the Previous and Next keyframes, as shown below:
Click the Next Keyframe button (>|) to move to frame 60. With the cat : Sprite Renderer.Color curve expanded, change the values for Color.r and Color.b to 0, as shown below:
As you can see in the Scene or Game views, or in the Inspector‘s Preview pane (if you still have cat selected in the Hierarchy), your cat is a very bright green. You could tweak the color values to make the cat appear a more zombie-esque hue, but this will be fine for Zombie Conga.
Preview the clip by pressing the Play button in the Animation window. Uh oh, I think kitty is gonna be sick!
You now need to make the cat transition from CatWiggle to CatZombify. Select cat in the Hierarchy and switch to the Animator view.
Right click on CatWiggle, choose Make Transition, and then click CatZombify.
Play your scene and the cat appears, wiggles a bit, turns green, and then stops moving. However, after turning fully green it resets its color to white and transitions to green again, over and over.
You’ve seen this problem before. Try to solve it yourself, but if you get stuck, check out the Spoiler below for the answer.
Now when the turns green, it stays green. Purrfect. Get it? Because it’s perfect, but it’s a cat, and cats purr, so I used “purr” in place of “per”. I don’t want to brag, but I’m pretty sure I just invented that. :]
You have the transition from CatWiggle to CatZombify set up, but it occurs as soon as the cat starts wiggling. In the actual game, you’re going to want the cat to keep wiggling until the zombie touches it, and then you’ll want it to turn green. To do that, you need CatWiggle to loop until a specific condition triggers the transition.
Animation Parameters
Unity allows you to add to an Animator Controller any number of user-defined variables, called parameters. You can then reference these parameters in the conditions that trigger transitions.
With cat selected in the Hierarchy, open the Animator view. Click the + in the lower left of the window, where it says Parameters, and choose Bool from the popup that appears, as shown below:
This parameter will be a flag you set to indicate whether or not a cat is a member of the conga line, so name it InConga.
Your Animator view’s Parameters should look like the following:
In the Animator view, select the transition you created earlier between CatWiggle and CatZombify.
In the Inspector, click the combo box under Conditions and you’ll see that there are now two options, Exit Time and InConga. Choose InConga, as shown below:
Be sure the combo box that appears to the right of the InConga condition is set to true, as shown below:
Now play your scene and notice how the cat appears and starts wiggling, but doesn’t turn green. In the Animator view, you can see how the cat continues looping in the CatWiggle state:
With the scene running and both the Animator and the Game views visible, click the empty checkbox next to InConga in the lower left corner of the Animator view. As soon as you do, you’ll see the animation state transition to CatZombify, and the cat in your Game view turns green and its wiggling smoothly comes to a halt.
Stop the scene. In the next part of this tutorial series, you’ll set the InConga flag from a script when the zombie touches the cat, but for now, you’ll just finish up the rest of the cat’s animations.
bool
to trigger a state change, but you can add parameters of type float
, int
, and trigger
, too. For example, you might have a float
parameter named “Speed” and then set up your Animator Controller to transition from a walk to a run animation if Speed exceeds a certain value.
Trigger
parameters are similar to bool
ones, except when you set a trigger and it initiates a transition, the trigger automatically resets its value once the transition completes.
Practicing What You’ve Learned
Right now the cat can appear, wiggle, and turn into a zombie cat. These are all good things for a cat to do, but you still need it to hop along in the conga line and then go away.
CatConga Clip
The actual logic to move the cats in a line following the cat will have to wait for the next part of this series, which focuses on finishing all the code to make this a playable game. For now, you’re only going to create the Animation Clip and set up the transitions.
First, add to the CatConga Animation Clip a curve that adjusts the cat’s Scale. The scale animation should start and end with values of 1, and be 1.1 at its midpoint. The clip should last for 0.5 seconds and should loop.
Now go. Animate.
Preview your clip by pressing Play in the Animation view. If you animated the scale properly, you should see a throbbing cat, as shown below:
You’ll have to use your imagination to envision it moving forward in sync with the animation. It looks like it’s hopping, right? If not, imagine better.
Now create a transition between CatZombify and CatConga. Try doing it yourself, but check the spoiler if you need help.
Play the scene now. While it’s playing, click the InConga check box in the Animator view. Behold, the zombification of a cat! Almost. After turning green, the cat immediately turns white again, like some sort of demon kitty risen from the undead!
The cat turned white again because the CatConga animation doesn’t set a color for the Sprite Renderer, so Unity took it upon itself to change the color back to its default of white. I’m really not sure if that’s a bug or expected behavior, but either way, there’s an easy fix.
Add a curve to CatConga to edit the Sprite Renderer’s color. You should definitely know how to do this one.
Inside the Animation view, move the scrubber to frame 0 in CatConga and set the Color.r and Color.b values to 0. Then press the Next Keyframe button twice to move to the keyframe at frame 30. Remember, that’s the button in the Animator view’s control bar that looks like >|.
You need to delete this keyframe. You can do so by clicking the diamond for cat : Sprite Renderer.Color in the curves list and choosing Delete Key, as shown below:
Additionally, you can get to these menus by right-clicking on the name of the curve in the curves list, or by right-clicking directly on a keyframe’s diamond-shaped marker in the timeline.
Now you should have a curve with a single keyframe at frame zero. This sets the cat’s color to green as soon as the clip starts and then makes no changes. Your Animation view now looks something like this:
Play your scene again, click the InConga check box in the Animator view, and watch as the cat turns undead and then stays undead, just like nature intended.
CatDisappear Clip
The goal of Zombie Conga will be to get a certain number of cats into the zombie’s conga line. When the zombie collides with an old lady, you’ll remove a couple cats from the line and have them spin off and shrink until they disappear, as shown in the following animation:
This is the last Animation Clip you’ll need to make for Zombie Conga, so it’s your last chance to try out this animation business on your own!
Try configuring the CatDisappear Animation Clip as described below:
- Make it last for two seconds.
- It should rotate the cat four full times. That’s 1440 degrees!
- The X and Y Scale values should go from 1 to 0 over the course of the clip.
- The cat should remain green.
- This clip should not loop.
- Create a transition between CatConga and CatDisappear that triggers when InConga is false.
If you get stuck on any of that, the following has you covered.
Now test the cat’s full suite of animations. Play the scene and watch your cat appear and start wiggling. Next, click the InConga check box in the Animator view to turn your cat green and make it start hopping. Finally, uncheck the InConga check box in the Animator view to make the cat spin away into nothingness. Bear witness to the sad, beautiful lifecycle of a cat:
Wait, didn’t that say “nothingness”? The cat disappeared from the Game view, sure, but take a look at the Hierarchy and you’ll see the cat is still hiding out in your scene:
You don’t want zombie cats sticking around in your scene after they disappear. That would make them zombie-zombie cats! Of course, you don’t want to remove a cat until you’re sure it’s done its animation, either. It’s a good thing Unity supports Animation Events!
Animation Events
Synchronizing game logic with animations can be tricky. Fortunately, Unity provides you with a built-in events system tied to your Animation Clips!
Animation Clips can trigger events by calling methods on the scripts attached to the animation’s associated GameObject. For example, you can add a script to cat and then call methods on it at specific times from within an Animation Clip.
Select cat in the Hierarchy and add a new C# script to it named CatController. This should be familiar to you from Part 1 of this series, but the following spoiler includes a refresher.
Open CatController.cs in MonoDevelop. If you aren’t sure how, just double-click CatController in the Project browser.
Inside MonoDevelop, remove the two empty methods in CatController.cs: Start
and Update
.
Now add the following method to CatController.cs:
void GrantCatTheSweetReleaseOfDeath() { DestroyObject( gameObject ); } |
You are going to configure CatDisappear to call this method when the clip finishes. As its name implies, this method simply destroys the script’s gameObject
to release the zombie cat to wherever zombie cats go when they die. Florida?
Save the file (File\Save) and go back to Unity.
Select cat in the Hierarchy and select CatDisappear from the clips drop-down menu in the Animation view.
Move the scrubber to frame 120, and then click the Add Event button in the Animation view’s control bar, as shown below:
This will bring up a dialog that lets you choose a function from a combo box. As you can see in the following screenshot, the default value in the combo box says (No Function Selected) and if you leave it like this, then the event will have no effect.
The combo box lists all of the methods you’ve added in any scripts you’ve attached to the GameObject. That is, it won’t list methods your scripts inherit from MonoBehaviour
, such as Start
and Update
.
In this case, you’ve only added GrantCatTheSweetReleaseOfDeath()
, so select it in the combo box and then close the dialog.
The timeline includes a marker for your new event, as shown below:
Hovering the cursor over an event in the timeline shows a tooltip that displays the method it this event will call, as you can see in the following image:
Right-clicking on an event brings up a menu that allows you to edit or delete the event, as well as add a new event.
For example, the following image shows a function that takes an int
:
Your event can be of one of the following types:
float
, string
, int
, an object reference or an AnimationEvent
object.
An AnimationEvent
can be used to hold one each of the other types. The following image shows the dialog when editing a method that takes an AnimationEvent
parameter:
Run your scene. Once again, click the InConga check box in the Animator view to zombify the cat, and then click the InConga check box again to uncheck it and watch as the cat disappears into a sandy after-afterlife.
More importantly, notice that cat no longer appears in the Hierarchy, as shown below:
In a real game you would probably want to recycle your cat objects rather than continuously create and destroy them, but this will be fine for Zombie Conga. Besides, do you really want to live in a world that recycles cats?
Bonus: Animator View Extras
This tutorial couldn’t cover everything involved with animating in Unity. Unity’s animation system, known as Mecanim, is quite sophisticated and was originally built for creating complex 3D animations. However, as you’ve seen, it works very well for 2D animations, too.
This section includes a few notes that weren’t mentioned anywhere else in this tutorial, but that may be helpful when you’re creating your own animations.
Any State
In addition to the states you worked with in the Animator view, there was also a teal rectangle labeled Any State, as shown below:
This is not really a state at all. Instead it is a special endpoint for creating transitions that can occur at any time.
For example, imagine you were writing a game where the player always had the ability to shoot a weapon, no matter what animation might be playing at the time the player tries to fire. Call its shooting animation FireWeapon.
Rather than creating a transition to the FireWeapon state from every one of your other states, you could create a transition to it from Any State instead.
Then, if this transition’s condition is met – in this hypothetical case, maybe a FirePressed bool
parameter is true
– then this transition will trigger, regardless of which state the Animator Controller happened to be executing at the time.
Sub-state Machines
In addition to Animation Clips, states in an Animator Controller can be sub-state machines. Sub-state machines primarily help you keep complicated state machines organized by hiding branches of a state machine under a single state node.
For example, imagine a series of Animation Clips that make up an attack, such as aiming and firing a weapon. Rather than keep them all visible in your Animator Controller, you can combine that series of clips into a sub-state machine. The following image shows a hypothetical Animator Controller for the zombie, where it can transition from walking to attacking:
And the following image shows a simple set of states that might define an attack:
You connect transitions in and out of sub-state machines the same way you would regular states, except a popup menu appears that you use to choose the specific state to which to connect.
For a detailed look at sub-state machines, read this section of Unity’s manual.
Blend Trees
Blend Trees are special states you can add to an Animator Controller. They actually blend multiple animations together in order to create a new animation. For example, if you had a walking and a running animation you could use a Blend Tree to create a new animation in between those based on run speed.
Blend Trees are complicated enough to require their own tutorial. To get you started, Unity’s 2D character controller training session includes a great example of using a Blend Tree to choose the appropriate Sprite for a 2D character based on the character’s current velocity.
You can read more about Blend Trees in Unity’s manual.
Layers
In the upper-left corner of the Animator view is a section labeled Layers, as shown below:
You can use layers to define complex animations that occur on a 3D character. For example, you might have one layer that controls a 3D character’s legs walking animation while another layer controls the character’s shooting animation, with rules for how to blend the animations.
I don’t know if you can use layers for 2D characters, but if you ever want to learn more about them, check out the documentation here. Please leave a comment if you know of a way they can be used in 2D games. Thanks!
Bonus: Scripting
The next part of this series will be mostly scripting, and one of the things you’ll learn is how to access from your scripts the parameters you defined in the Animator view.
However, I’m sure some readers won’t want to wait for the weeks it will probably take before that tutorial comes out. I’m not going to explain it here, but if you just can’t wait, here is some code that will let you access InConga
from a script:
// Get the Animator component from your gameObject Animator anim = GetComponent<Animator>(); // Sets the value anim.SetBool("InConga", true); // Gets the value bool isInConga = anim.GetBool("InConga"); |
It’s best to cache the Animator
component in a class variable rather than getting it every time you need it. Also, if speed is an issue, use Animator.StringToHash
to generate an int
from the string
“InConga”, and then use the versions of these methods that take an int
instead of a string
.
Where To Go From Here?
This tutorial covered most of what you’ll need to know to make 2D animations in Unity. You can find the completed project here.
The next and final installment of this series will focus mostly on scripting, but will also show you how to implement collision detection using Unity’s new 2D physics engine. By the end of Part 4, you’ll have cats dancing in a conga line, win/lose states and an intro screen. You’ll even throw in some music and sound effects just for fun.
To learn more about building animations in Unity, take a look at these resources:
- Check out Unity’s Animation tutorial videos.
- Unity’s 2D character controller training session. In addition to the Blend Tree example mentioned earlier, this session goes over animating sprites while it demonstrates the creation of a 2D character controller.
- The Animation section of Unity’s manual.
- Unity’s reference to the various animation components.
Please let us know if this tutorial was helpful. Leave remarks or ask questions in the Comments section.
Unity 4.3 2D Tutorial: Animation Controllers is a post from: Ray Wenderlich
The post Unity 4.3 2D Tutorial: Animation Controllers appeared first on Ray Wenderlich.