This really quick tutorial uses the Unity Mecanim system to produce the simplest possible sprite-sheet animation. When we are finished our character will be able to stand still or walk left and right. We will achieve this by stopping the sprite-sheet animation when the player isn’t pressing left or right and starting the animation when he is. In addition, we will invert/flip the sprite-sheet when the player changes direction to avoid an accidental Michael Jackson moon-walking effect.
Start Unity and click New. Name your project Sprite-sheet animation, select the 2D option and click the Create Project button. Before we get started adding our sprite-sheet to the project, we will need some animation-specific tabs open in the Unity editor. In the main menu select Window | Animation to open an Animation tab. Now select Window | Animator to open an Animator tab. We will see the difference between these similarly named tabs as we proceed. It doesn’t really matter where these tabs are added because they will work anywhere and you can easily re-size them to accomadate whatever you are doing.
Creating a game object and adding an Animator component
Before we move on to the animation proper, we need a game object in the scene. Right-click in the Hierarchy tab and select Create Empty…. Rename the new game object to Player. Make sure the Player object is selected in the Hierarchy tab and click the Add Component button in the Inspector tab. Choose Miscellaneous | Animator. Be sure to choose Animator and not Animation. So we can eventually move the character and add a RigidBody 2D component as well. In the RigidBody 2D component set the Gravity Scale to zero and check the Freeze Rotation option. We don’t want Bob spinning and falling. In a full game, we would almost certainly leave gravity enabled and provide a level for the player to jump and fall around in. For this tutorial, it is convenient to disable this behavior.
All the code and graphics that you need for this project are contained on this page. However, if you are kind enough to help spread the word about this tutorial, there is a nice little download that contains the code and the graphics in one handy zip file.
Importing the sprite-sheet
Download this sprite sheet which contains all the frames of animation for a simple walking animation. Note that in the image at the top of the page, I have added a pretty background. This isn’t necessary to complete the tutorial.
Right-click in the project tab and select Import New Asset…. Browse to the player.png image you just downloaded and click the Import button. In the Inspector window change the Sprite mode option from Single to Multiple. Click the Apply button in the Inspector tab. Now Unity knows to treat player.png as a sprite sheet with multiple frames of animation.
Slicing the sprite-sheet
Again in the Inspector window, click the Sprite Editor button. You might find it useful to drag the tab of the Sprite Editor window and dock it. I docked mine alongside the Projects tab as shown in the next image.
Click the Slice drop-down that is highlighted in the previous image and check that the options Automatic, Centre, and Delete Existing are chosen. Some sprite sheets have their images organized in different ways. That is why there are a number of options to choose from. The default options just mentioned are fine for slicing up Bob. Click the Slice button and Unity will slice the sprite sheet into five individual frames of animation. Make sure to click the Apply button at the top-right of the Sprite Editor tab. In the next image, you can just about see the lines representing the results of the slice operation.
Before we create the actual animation, Select the Player object in the Hierarchy tab, and then in the Inspector tab select Add Component | Rendering | Sprite Renderer. Now drag the player sprite from the Project tab to the Sprite field of the Sprite Renderer component.
Creating the “walk” animation
Select the Project tab and notice that the appearance of the player asset has changed slightly as shown next.
Click the little triangle icon shown in the previous image and then you can see each of the frames of animation that we sliced up previously.
Next, make sure the Player object is selected in the Hierarchy tab. Now, find the Animation tab that you opened at the start of the project and click on it. Your Animation window should now look like this image.
Click the Create button and name the new animation Walk. In the Project tab shift left click each of the frames of animation to select them all. Now drag them from the Project tab into the Animation tab. Your Animation window should now look like this image.
In the Animation window, change the Samples value to 12. This will allow for 12 frames per second of animation. This will appear like a frantic but discernible running motion. We have one more step before we can start coding the script that will make all this work.
Configuring the animation states and transitions.
Make sure that Player is selected in the Hierarchy tab and click on the Animator tab that we added at the start of the tutorial. You will see something like this.
In the previous image, you can see our Walk animation state joined to another state called Entry. This means the Walk animation is the default state and will start to play as soon as the game is run. We want no animation to play at first and the walk animation to start only when the player is moving the character. We can achieve this in a few steps.
Creating and configuring transitions between walk and idle and configuring them with parameters
So that our character does not immediately start its walking animation we will create a new state called Idle and make it the default state.
Right-click in the Animator tab and select Create State | Empty. Rename the state, using the Inspector tab and call it Idle. Next, right-click the Idle state and select Set Layer as Default State. This is what the Animator tab should look like now.
You can see that the Idle state will be entered after the Start and as the Idle state is empty, no animation will play until we tell it to in C# code. We will now create two transitions. One from Idle to Walk for when the player starts moving and one from Walk back to Idle for when he stops again.
Creating the transitions
First, we need a parameter that will be used to decide if the time is right to transition. In the Animator tab, click the Parameters tab and then click the + icon to create a new parameter, choose the Float type and name the parameter speed. This makes sense because it is the player’s speed that will determine if the walk animation is playing or not.
Now we can make the transitions between Idle and Walk. Right-click Idle, select Make Transition and then left-click Walk. You can see the new connection/transition between the two.
Left-click the new transition/connection and we can configure it in the Inspector tab. Find the Idle -> Walk label and click it. Now, still in the Inspector tab, find the Conditions tab. Click the + icon to add a new condition. To be clear about what we are doing, we are adding a condition on which the transition (from Idle to Walk) will occur. Actually, we are done with this transition because the default values shown in the next image are exactly what we want.
You can see in the previous image that the transition from Idle to walk will occur whenever speed is greater than zero. We will see how the Animator will be fed values for speed from a C# script soon.
Let’s quickly make the transition from Walk to Idle and then we can start coding. Right-click the Walk state and choose Make Transition. Left click the Idle state to join them up. Left-click the new transition/connection. Using the same steps as we did before, add a condition that will cause a transition from Walk to Idle whenever speed is less than 0.01. This is what it will look like when you’re done.
Let’s write some code.
Coding a PlayerController script to bring the animations to life
I will just throw the code at you in one lump and then go through it once you have the project working. Note also there are lots of comments in the code to make it clear which section does what. Select the Player object in the Hierarchy tab. Click the Add Component button in the Inspector tab and select New Script. Name it PlayerController and then click the Create & Add button. Add to and edit the script to contain the following code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
using UnityEngine; using System.Collections; public class PlayerController : MonoBehaviour { // What is the maximum speed we want Bob to walk at private float maxSpeed = 5f; // Start facinf left (like the sprite-sheet) private bool facingLeft = true; // This will be a reference to the RigidBody2D // component in the Player object private Rigidbody2D rb; // This is a reference to the Animator component private Animator anim; // We initialize our two references in the Start method void Start () { rb = GetComponent<Rigidbody2D> (); anim = GetComponent<Animator> (); } // We use FixedUpdate to do all the animation work void FixedUpdate () { // Get the extent to which the player is currently pressing left or right float h = Input.GetAxis("Horizontal"); // Move the RigidBody2D (which holds the player sprite) // on the x axis based on the stae of input and the maxSpeed variable rb.velocity = new Vector2 (h * maxSpeed, rb.velocity.y); // Pass in the current velocity of the RigidBody2D // The speed parameter of the Animator now knows // how fast the player is moving and responds accordingly anim.SetFloat("speed", Mathf.Abs(rb.velocity.x)); // Check which way the player is facing // and call reverseImage if neccessary if (h < 0 && !facingLeft) reverseImage (); else if (h > 0 && facingLeft) reverseImage (); } void reverseImage() { // Switch the value of the Boolean facingLeft = !facingLeft; // Get and store the local scale of the RigidBody2D Vector2 theScale = rb.transform.localScale; // Flip it around the other way theScale.x *= -1; rb.transform.localScale = theScale; } } |
You can run the game now and use the arrow keys to walk left and right.
The animation is of a very basic quality but hopefully, you know enough now to source or create your own sprite sheets, slice them up, and create some transitions. It might be worth mentioning that the Idle state doesn’t have to be empty, it could contain an animation of a character scratching his head, picking his nose, or heaving his chest to get his breath back.
This is how the code works.
Understanding the C# animation code
In the PlayerController class, first of all, we declare some variables to hold the maximum speed, the horizontal direction the sprite is facing, a reference to the RigidBody2D component and a reference to the Animator component. In the Start method which executes when the object is first created, we use the GetComponent method to initialize the two references to the components I just mentioned.
Most of the action takes place in the FixedUpdate method. By placing the code in FixedUpdate we are guaranteed that the code will be executed a consistent number of times per second of the game. Here is what the code does.
Input.GetAxis is used to load a value into the h float variable. The Input.GetAxis method returns a value between -1 and 1 which represents the extent to which the player is moving left or right. Note that if you have a game controller attached to your PC it will work with it as well as the keyboard arrow keys.
Also in FixedUpdate, we assign a new velocity to the RigidBody2D via the reference rb.
After this, we use the anim reference to call the setFloat method to set the value of the speed parameter of the Animator. The Animator now has all the information it needs to make decisions about when to transition to and from the Idle and Walk states. This is all we need to do to make the animations play at the right time. You could run the game without completing the rest of the code. Bob would walk to the left normally and moonwalk backward to the right.
The if and else if code structure which follows simply compares the corresponding values of h and facingLeft. If the player is moving left h will be less than zero and if the player is moving right h will be greater than zero. Using this information we can determine if we need to reverse the image and avoid the whole Michael Jackson thing. If we need to reverse the image the code calls reverseImage.
In the reverseImage method we, of course, reverse the image. The individual steps are fairly comprehensively documented in the code comments.
If you have been following along from the start of my Unity 2D tutorials, it is time to make our second full game – a simple 2D platformer.
Where I can find the second full game – a simple 2D platformer?
Hi Roger,
Really sorry! Haven’t done it yet. Get to it as soon as I can.
John
Brilliant, thank you very much. Cant wait for it.
Thanks a lot for this tutorial, it helped me to be able to make attacking animations for my weapons in a simple 2D RPG
Glad this helped and thanks for the message.