Intro to Mecanim
I think anyone who has ever enjoyed a giant robot based show can agree that Mecanim should be spelled ‘Mechanim’, but this is a battle I’ll never win, and so, we’ll move on.
Mecanim is Unity’s fairly robust animation system, and once you get past the initial learning curve, there’s really a ton you can do with it. Its rather hard to determine Mecanim’s finest feature--It can cleanly blend between animations for natural transitional movement, the ease in which it integrates into scripts makes even the most novice of programmers feel accomplished, and the real time feedback when the game is playing makes debugging pretty simple.
But, for all of that good, Mecanim can be a fairly daunting beast for someone who is brand new to the world of game development. There’s a lot of terminology utilized within the system that can seem pretty nonsensical, and the fact that you’re more or less expected to use code to make it work in game makes it seem like the last thing a newbie would want to work with.
The great news is that once you pull back the curtain, there’s really not a ton to the system at all.
Let’s start on the ground floor. Mecanim is a system based on state machines. What are state machines? Glad you asked.
Right click and choose ‘open link in new tab’ to view the video on YouTube. |
Thank god. I nearly quit right there, you know.
So now that we know what state machines are, we’ll be able to approach Mecanim with much better understanding. Knowing that we essentially only need to keep track of actions and rules makes the whole matter much easier.
Before we jump in, let’s take a quick peek at some Unity’s specific terminology. That way when I start slinging it around in the rest of the document, you’ll know what I’m talking about.
(Hope you came here for animal based explanations to problems.. Because that’s what’s happening.)
Animation: The change that is occurring to the object in question over a specified length of time. (Okay this isn’t Unity specific but it’s in the doggy picture)
Animator: The object that is being animated.
Animation Controller: The ‘brain’ of the Animator.
In the image above, a doggy is driving a car. Since the dog is the driver, he takes on the role of the Animation Controller. He knows what movements he can perform in his vehicle, and he knows where he wants to go. The car is the Animator, as it’s the thing being physically moved over time. Finally, the Animation is the movement of the car. No color codes for that, as it’s not really a new term…
Got all that? Then let’s get into Unity!
We’re going to be using an example scene found on the Unity asset store. If you haven’t created an account on the asset store yet, I recommend waiting until after you finish this document, because you’re going to get lost in the wonderland that is free and cheap Unity assets. And all of your money will go away. Of course this might just be my personal life experience, but I prefer to think of this as a global phenomenon and not a personal problem.
...Anyway, the asset we’re using is Medieval Toon house by the publisher Night Forest.
(pretty)
Hot tip! Whenever using downloaded assets from the Unity store, make sure to check that any object you want to animate is not set to Static. When an object is set to Static, you’re telling Unity that under no circumstances is it supposed to move in game (it’s a bit more technical than this, but for animators, this is a good enough answer). Unity will allow you to animate it in the scene view and even preview it in animation mode, but the final result will be...no result at all. The Static tick box is located in the inspector, directly to the right of the object’s name.
Make sure that your animated objects always have the static box off.
Let’s get started!
If you don’t already have them up, go ahead and open the Animation and Animator windows. They can be both found under the Windows dropdown at the top of the workspace.
If you happen to be working on a multi-monitor setup, I highly recommend dedicating one of your screens to these windows. If not, dock them where you find to be the most convenient (I prefer behind the project tab, but that’s just me).
For this example (and to reinforce the concepts we learned from the video), we’re going to be setting up a Mecanim system for the front door of the cabin. Our first task will be to create all of the animations. We’re going to follow the logic set up in the video, so our animation to-do list consists of:
Now, technically speaking we only need two of the above animations: Door closed, and door opening. We can force the door opening animation to wait for us at its last frame until a certain point, then reverse it and return it to the closed animation, buuuuut that doesn’t give us nearly enough practice to become comfortable with the animation process, thus, we take the long way. In coming weeks, we’ll learn how to be more efficient with our animations but until then, focus on becoming comfortable with the software!
(It’s important to note that although we’ll be building all of our animations at once in this example, it’s definitely not a requirement. Unity is really great about allowing you to iterate on pretty much anything, so if later down the line you want to add new animations to your objects, or change the way your Mecanim system works, you totally can.)
Make sure you have your animation window where you can get to it, and select the front door. In the upper left hand region of the animation tab, directly left of the sample input, click on the ‘invisible button’ to choose to create a new clip.
Remember to keep things organized by creating a folder for your animations. Save this first clip as doorClosed.
The clip name will now appear in the ‘invisible button’, making it a visible button...Yay?
This is going to be an empty clip, so we really just need one keyframe on the rotations so the door knows where it’s going to be sitting. Click on the big Add Property button, and navigate to the transforms section, and finally select Rotations from the list.
Unity will automatically create start and end keyframes for you at the rotation your door is currently oriented.
It doesn’t hurt anything if you leave that end keyframe, but I prefer just to delete it all the same. So long as we have that starting keyframe, our mission is accomplished, and we can move on to our next animation (wasn’t that fast!)
Click on the no-longer-invisible-button-that-now-has-the-clip-name (okay, that’s officially too long now. We’re going to call it the clip button from here on out) clip button, and create a new clip. Let’s call this one doorOpening.
The clip button will list the newest animation name that you’ve created, but don’t worry, all of your other animation are readily available if you click on the button’s drop down. Unless you select an item and hit ‘Delete’, you will never lose anything in Unity!
In this animation, we’re going to have the door rotate to an open position. Unity uses an auto-key system, so all we need to do is move our time slider to where we want the animation to end, and rotate our door to it’s fully open point.
(Unity uses autokeys, so you can just set your time slider and start animating!)
Once you’ve rotated your door open, use the animation preview button (directly next to the record button in the animation tab), to check the rate of your animation. If you want the door to open more quickly or slower, simply drag the keyframes to your new desired location. Repeat until you’re happy.
Because we’re going to be referencing the door open position in other animations, I like to make that final rotation position a whole number so it’s easier to remember.
Our door opening animation is finished, so let’s create a new clip and call it doorOpen.
This is another empty state, so we’re going to repeat the process we used to create doorClosed. The only difference is that after you delete the end keyframe, return to the key at frame zero, and adjust the Y rotation so it’s the same as the end keyframe of your doorOpening animation. This way, our empty state will be of the door standing open in the same position where the previous animation ended.
Last but not least, let’s create a final animation clip and call it doorClosing. Creating this animation is the same as what you did for doorOpening, but obviously, your first keyframe will be of the door in its open position. Animate that door closing all pretty like.
And with that, our animations are done! Now we just need to set them all up in Mecanim.
Switch over to the animator tab, and you should see something similar to this. There will be rectangular nodes for each one of our animations, in addition to three extras: Any State, Entry, and Exit. We’ll leave any state for another day, but Entry and Exit will be utilized in this tutorial!
The animator window is a 2D environment, meaning you’ll only be able to pan around inside it. Holding alt and the left or middle mouse button will produce the same result, while the right mouse button doesn’t do anything--there’s no zooming in and out in the Animator window. Don’t worry, when we start building more complex setups there’s a way to deal with the limited space, but for today, it wont be an issue. To move nodes around, simply click and drag.
You’ll notice that the first animation we created is bright orange. This indicates that it’s the default animation node, and will play as soon as the game starts. If you want a different animation to be the default animation, simply right click over it and choose ‘Set as Layer Default State’.
The other thing that stands out is the fact that Entry is already attached to doorClosed via an arrowed line. This line represents transitions between animations in Mecanim. As soon as the game starts, Entry is going to transition to whatever animation it’s set to. It seems a little pointless right now since we’ve already declared what we want the default animation to be, but its use will become apparent at the end of this tutorial.
Let’s begin setting up our transitions. We want our door to go from its closed animation to its opening animation when a rule we specify in a moment has been met. In order to create a transition, right click over doorClosed, and choose Make Transition. The transition line will follow your mouse until you click on the node you want to connect it to.
Now if you select the transition itself, you’ll be able to see all of the information available about it in the inspector. Near the bottom of the inspector, you’ll see the conditions section. The conditions are the rules that we need to set to cause the transition we just created to occur. Right now we don’t have anything to set in our conditions, so let’s change that!
Empty for now.
On the left side of the Animator window, you can see the layers section. We’ll get into detail about what those layers are another day, but for now, click over to the tab behind it, which is named Parameters.
Empty too, for the moment.
Parameters are best thought of as the verbs in our rules.
“If this thing right here happens, then go ahead and make the transition.”
In the state machine video, if the button was pressed, the door was supposed to transition to its opening state. If we were able to peek at the parameters of that door’s animator, we’d probably see bottonIsPressed, or something similar.
There are four different types of parameters to work with, but today we’re going to start out with Triggers, as they’re the easiest of the bunch.
Triggers are exactly what they sound like...They’re something that causes something else to happen.
To give a real example, let’s think about a trigger on a gun. You only need to interact with it in one way (pulling it), and once you do, a big event occurs that you can’t really easily stop (bullet fires).
Triggers are great parameters to start with, since we essentially just tell Unity to “do this thing!” and Unity goes ahead and does that thing for us.
So, let’s create our first Trigger. Once you’ve done so, a name field will open up for us. Go ahead and name this Trigger opening.
Now, we will be calling these parameters in code, so it’s best to keep their names as simple, yet as descriptive as possible. Spelling and letter casing will be extremely important, so remember to spell words correctly, and keep track of their case (it’s okay to have upper case letters--just remember where you use them!).
Return to the transition by selecting it, and going to its conditions section in the inspector. Now that we have a parameter, we need to load it in!
Click on the + button to add a condition. Since we only have one parameter, it’s automatically loaded in (convenient!).
The transition from closed to opening is now complete. If you want to see how the system will work, make sure your door is still selected in the scene view (so that we can see the Animator working in play mode), and press the Play button at the top of the window.
Your door should remain in its closed state. If it transitions directly over to the opening animation, double check your transition. If everything looks right, leave play mode, and wiggle the doorOpening animation node around a little. Sometimes Unity doesn’t notice updates were made to the Animator until one of the nodes is manipulated. Sounds weird, but it is what it is!
After you’ve established that your door is staying in the closed state, press the little circular button next to your opening trigger in the parameters section. The door should transition to open!
Two things seem to be a problem, however. Firstly, the door doesn’t immediately open when you press the trigger button. That’s because the animation is currently set to have Exit Time. In other words, we wont transition from one animation to the other until the first animation is finished. While that’s good in some circumstances, for our door, it doesn’t make much sense. Exit play mode, and reselect the transition. In the inspector, there will be a tick box for ‘Has Exit Time’. Uncheck it.
Make sure Has Exit Time is unchecked
The other issue you probably noticed is that while your door transitions to the open animation, that animation loops! By default all animation clips you create in Unity will be set to looping. In order to fix this, simply locate your animations in the project, and uncheck ‘loop time’ in the inspector on each animation you select.
In our case, we don’t want doorOpening or doorClosing to loop.
When you select an animation in the Project tab, you’ll be able to see the loop time tick box in the inspector. Make sure to uncheck it!
With these two adjustments made, Press play again and preview your door. It should be standing still until you press the opening Trigger, after which, it should spring open!
Next we want to transition from our opening state to our open state. Add a transition from doorOpening to doorOpen...and you’re done! When you don’t add a condition to a transition, the animation will play through once, and immediately transition to the next state, which is precisely what we want to have happen in this situation!
Now we need to tackle getting the door to close again after another rule is met. Following the same directions you used to create opening, create another trigger parameter named closing. Create a transition between door open and doorClosing, and set the condition to be the closing parameter we just created.
Finally, let’s create one last transition, this time from doorClosing to Exit. The Exit node is pretty awesome, because it’s basically a restart node. Whenever a state transitions itself to the Exit node, the entire state machine will restart from the beginning, starting with the Entrance node. Told you it would come in handy!
So now, we have a completed state machine!
The only problem that remains now is that we can’t really expect our players to somehow dive into the editors and click those trigger buttons every time they want to open the door. So, we’re going to need to create some kind of functionality that will take care of activating those triggers at the necessary time. The easiest way to do this is to create a zone in our game that will activate the triggers once our players enter it.
To create this zone, we’re going to use a cube. All 3D objects in Unity can be found under the Game Objects drop down window.
Once you have created your cube, move it and scale it so its sitting on the front stoop and into the house, as illustrated in the next image. Rename the cube to doorTrigger.
Arrange the cube so it’s inside the house. That way the player will be able to exit too!
In the inspector, tick the isTrigger check box in the doorTrigger’s box collider section. This way the doorTrigger will understand that it’s purpose isn’t to block anything, but rather, look for anything to interact with it.
Be sure to tick is Trigger!
It’s going to be a little difficult to watch our animations with the doorTrigger in the way, so we’ll make it invisible, but still functional in the world. To do this, we’ll turn off its Mesh Renderer.
Directly below the collider section in the inspector is the mesh renderer. Untick the box right next to the words ‘Mesh Renderer’ to disable it. You’ll see that the box disappears, but the green collider remains.
Now that we have the zone created, we need to create a script to handle our transition rules for us.
With the doorTrigger select, go to the bottom of the inspector and click the Add Component button. At the bottom of the list, choose New Script. Name it doorTrigger and make sure the type is set to javascript. A new inspector node will appear with the title of your script.
Double click on the script name (the part that appears in the little slot to the right of Script) to get the script editor to open. For PC, it will be MonoDevelop, for Mac, it will be Unitron.
Any script we create in Unity will have some default functions inside. In this case we wont be using either Start or Update, so we can get rid of both. Remember to leave #pragma strict at the top.
Ready to go!
The script we’re going to make is extremely simple, so don’t worry if you haven’t scripted before now. Before we move forward, there are two terms you should be familiar with: Variable and Function.
Variables are best thought of as containers. Here’s how my programming teacher explained it to me: Think of an old fashioned apple box. One of those wooden numbers with fine American craftsmanship from eras gone by. It's finely sanded and varnished, but most importantly it has a very lovely painting of a Red Delicious with the word 'APPLES' printed below it. Anyone who sees it knows without a shadow of a doubt that this box is for apples, and apples alone. (Now here there was a side conversation about hippies [though it really should be hipsters now!] repurposing found Americana and ruining analogies, but I'll leave that out) Since we don't have to worry about figuring out what this fine box is for, we can focus on what's inside. On this particular day, there are eight apples lovingly placed in it by the farmer. Our apple box has eight units in it. In codespeak that would be var appleBox = 8;. Now let's say that little Timmy ran over to the box and added two more that he was able to pick from the tops of the highest branches, because he's small and expendable in the eyes of the farmer. Now the box has 10 apples, but they're *still* apples, so that's okay. The codespeak would now be var appleBox = 10;. Numbers can change all day and that's just fine, because thanks to our box, or our variable name that we declared to this container, we always know what that number is referring to.
Functions: Are best thought of as to-do lists for computers. The first part of a function will be the declaration, or ‘name’ of our to-do list. After that, we start our list with curly braces (also known as mustaches), and list all the stuff our computer needs to do. Finally, we end the list with a closing curly brace, and the function is complete. Here’s an example of what a normal to-do list looks like in a way that we understand, versus how it’s formatted for computers:
Human To-Do list | Computer To-Do list |
Grocery Shopping [] Eggs [] Milk [] Flour [] Spinach | function GroceryShopping ( location : Store) { get Eggs; get Milk; get Flour; get Spinach; } |
Computers are much more specific and literal, but other than that, there’s not much difference. Even the formatting looks vaguely familiar.
Here’s the script we’ll be writing up:
var anim : Animator;
function OnTriggerEnter (other : Collider) {
anim.SetTrigger ("opening");
}
function OnTriggerExit (other : Collider) {
anim.SetTrigger ("closing");
}
So, what does this mean?
var anim : Animator;
(We’ve created a variable to hold our door Animator. The reason why we’ve done this rather than explicitly reference our door is to make the script more recyclable. Now we can use it with any Animator, so long as it has a trigger called opening, and a trigger called closing. The reason why the variable is called anim is because I arbitrarily decided to name it that. I could have called it steve and it still would have worked just fine)
function OnTriggerEnter (other : Collider) {
(We’re using one of Unity’s preset function types here, and when you think about the name, it makes sense as to what we’re trying to do. This script is going to be attached to our doorTrigger, and we want it to fire our trigger parameters when our player enters it. Thus, this is the to-do list to follow when something enters the trigger. The (other : Collider) part helps get things a little bit more specific. We’re telling the script what sort of thing we’re waiting to enter the trigger. ‘Other’ refers to pretty much anything other than the trigger itself. Collider is the thing we’re looking for to enter the trigger. So, when anything with a Collider enters the trigger, do the stuff below!)
anim.SetTrigger (“opening”);
(Now we’re finally in the to do list itself. It only has one thing, but that’s fine! That’s all we want the computer to do. This line is accessing the anim variable, so basically we’re telling the computer to look at whatever we plugged into the anim container. Next, we’re telling it what we want to do with the Animator we just had it access: set the trigger. Now, in more complex state machines we might have a ton of triggers, so we have to specifically say which trigger we want to set, thus (“opening”). You’re probably noticing at this point that parentheses are used to give the computer more data on a subject as needed, but what’s the deal with the quotations? Anytime you’re trying to feed the computer a human term like a name [and that parameter is something that we named, remember], we need to let it know what we’re trying to give it human words, not computer words. Human words are referred to as strings. By surrounding strings in quotation marks, the computer just takes the words as they are, rather than try to comprehend them. In this case, the computer will go into our Animator, find the trigger with the matching string, and that will be that.
}
(Our list is done, so we close it with a curly bracket facing left.)
function OnTriggerExit (other : Collider) {
(This is the exact deal as above, except it’s looking for when that object leaves the triggerCube!)
anim.SetTrigger (“closing”);
}
So, let’s type that script into our script editor.
...And save! Go back into Unity. If you see any red text at the bottom of the screen, it means there was some kind of error in your script. Odds are, you misspelled something! Go back and check! If there’s no red, you’re in the green!
The last thing we need to do is manually add in the Animator to the new slot that’s become available in our script.
To do this, drag your door from the hierarchy to that slot. Unity will automatically separate out the animator from the object itself.
Finally it’s time to test our system! We need to add a character controller to the scene, so if you don’t already have characters imported into your Unity project, do so by going to Assets => Import Package => Characters
Once imported, the Characters will appear in the Standard Assets folder of your project. We’ll use the first person rigid body controller for this scene, so to track it down, dive into the following folder structure:
Standard Assets => Characters => FirstPersonCharacter => Prefabs
Drag the RigidBodyFPSController into your scene. If you dislike how short it is, adjust the height in the Capsule Collider section of the Inspector. Do not just manually scale the character with the scale widget! Also, be careful not to make your character so tall that they can’t fit into the door! A height of 3 usually does fine.
Moment of truth time, let’s test out our door!
Success!
Again, don’t forget to set your trigger into your doorway so the player can interact with it from inside of the cottage as well!
That’s all there is to it! Now go, create state machines! Remember, you can reuse that script for as many triggers as you like! If you want to make it more generic, make your parameter trigger names ‘start’ and ‘end’, so they make sense for any sort of animation!