3rd Person Animation Attacks

In the previous lesson, we set up a 3rd person controller and swapped out the default robot character with a character called Eve. In this tutorial, you'll learn how to adapt Unity's Input Controller so that we can set up a sword attack animation.

 

Unity Input System

In previous lessons, we got input from the user like this:

Input.GetAxis("Horizontal")
Input.GetAxis("Vertical")

This allowed us to grab control of the mouse. If we wanted to grab a key press on a keyboard, we did this:

Input.GetKeyDown(KeyCode.W)

However, this is now considered old technology. Unity has a new input system that it encourages you to use. The reason is that, in the old system, you have to write separate code for a keyboard and separate code for, say, a gamepad. With the new system, you just write one piece of code and it can be applied to keyboards and gamepads.

Unity's new Third Person Controller comes with the new input already set up for you. To see it in action, click on the Starter Assets folder in the Project area. In the Starter Assets folder, click on the Input System folder:

Starter Assets, Input System folder

Notice two items, here. One is the icon with the blue lightning bolt, which is the Input System itself. The other icon to notice is the Starter Assets Input script, which we'll come back to later. But double click the Starter Assets icon (the first icon). You'll see a new screen opening up. This one:

Unity Input System screen

On the left, there's something called an Action Map. Unity have set one up called Player. The Player Action Map has Actions set up: Move, Look, Jump, and Sprint. The idea is to map your actions to keyboard keys, gamepad, Xbox controllers, mobile devices, etc. One you've set up your maps and actions here, you can reference these in your code.

Expand the Move item to see the following:

An action map with some actions already set up

The WASD part is the parent item. If you were to click on it, you'd see that there's a property called Composite Type. This is set to a 2D vector, meaning the X and Z values.

The blocks in pink are where the actions happen. For example, the Up move action is being mapped to the W [keyboard] key. You can also move Up if you press the Up Arrow [Keyboard]. Notice that the Left Stick [Gamepad] is also part of the Move section. So, whether you use the left stick on a gamepad or the keys on a keyboard, these actions will move the player. Well, once the code is wired up, anyway.

Let's set up our own action. We want Eve to swing her sword when a key on the keyboard is pressed (we won't set up a gamepad action here). We'll use the F key to swing the sword.

To add a new action, click the plus symbol at the top of the Actions section:

Adding a new action

Rename the new action Attack (you can call it anything you like, though):

A new action added to the input system

Notice that the Action Type property on the right is set to Button. This means either a key press or a button press on a gamepad.

The action is not bound to anything, at the moment. So, click where it says No Binding. On the right, click the dropdown where it says Path:

Adding a binding to an action

From the dropdown, type the letter F. Thne select the F [keyboard] item:

The F key set up as a binding

Your Input dialog box should look like this:

A new action added to the map

Click the Save Asset button at the top, indicated by a red arrow in the image above.
You can close the input system down now, as we're done with it.

 

Input Code

In the same folder of the Projects area of Unity, where that file with the blue lightning bolt is, there's a C# file called Starter Assets Input:

Starter Assets code file

This file, as its name suggests, holds the code that processes the Input System. Double-click the file to open it up in your coding editor.

Notice this line at the top:

using UnityEngine.InputSystem;

Whenever you're dealing with the Input System, you need a reference to this library.

Have a look at the variables set up at the top of the code. You'll see these four:

public Vector2 move;
public Vector2 look;
public bool jump;
public bool sprint;

They are all public variables. Two of them are Vector2 variables and two are Booleans. The Vector2 ones deal with the X and Z values coming from the keyboard, mouse, gamepad joystick, etc.

The Boolean variables, jump and sprint, will hold a value of true or false. True for jump, if you press the spacebar on a keyboard or the South button on a gamepad. If you held down the left shift key on a keyboard or the left trigger on a gamepad then sprint will be true.

Have a look at the code for jump, as an example of how the Booleans are dealt with. There are two methods in the code. These two:

public void OnJump(InputValue value)
{

JumpInput(value.isPressed);

}

public void JumpInput(bool newJumpState)
{

jump = newJumpState;

}

They are both public methods, one called OnJump and the other JumpInput. The OnJump method has parameter set up:

InputValue value

The value part is just a variable name that could have been called almost anything. The type of variable is InputValue. This is part of the Input System library. Inside of the curly brackets of OnJump is this:

JumpInput(value.isPressed);

JumpInput is a call to the second method. Notice what's between the round brackets:

value.isPressed

The value variable comes into play here. After a dot, the property isPressed is used. This is the part that detects if the spacebar or south button was pressed. This then gets handed to the JumpInput method:

JumpInput(bool newJumpState)

The new variable name is newJumpState. It is of type bool. So, a value of either true or false will be stored inside of newJumpState, depending on the value inside of isPressed.

The only line of code for the method is this:

jump = newJumpState;

This stores the value inside of the public jump variable that's at the top of the code.

With all this in mind, we can add our own code here for Eve's attack. Set up a new variable at the top of the code, just under the sprint variable:

public bool attack;

We can now add methods similar to the ones already there. Add these two methods:

public void OnAttack(InputValue value) {

AttackInput(value.isPressed);

}

public void AttackInput(bool newAttackState) {

attack = newAttackState;

}

We've called these methods OnAttack and AttackInput. They work in exactly the same way as the ones Unity has set up for us - record whether or not our attack button was pressed (the F key, for us).

 

Setting up the Animation

Save your code and go back to Unity. We'll need to hack another C# file that Unity has set up for us. But let's add the animation first.

Go back to Mixamo.com. Make sure you still have your Eve character displayed. Click on the Animations link at the top. Then do a search for Sword. You'll find a lot of animations displayed in the results. You can select any that you like. We went for Stable Sword Outward Slash. Download you animation. You can download it without skin:

Mixamo dialogue box

Once the FBX file is on your computer, drag and drop it into the project area of Unity.

With the file selected, have a look at the Inspector on the right. Click on the Rig tab and switch the Animation Type from Generic to Humanoid. For the Avatar Definition, change it from Create From This Model to Copy From Other Avatar. For the Source, click the tiny circle and select your Eve avatar again:

Rigging an animation

Selecting an Avatar

Click the Apply button when you're done.

Now we need to display the Animation Controller that's already been set up for us. So, in the Project area, move inside of the Starter Assets folder, then the Third Person Controller folder, then Characters > Animations. You'll find the Animation Controller in there:

An animation controller

Double click the Animation Controller to open it up. You should see this:

Make sure you are on the Layers tab rather than the Parameters one. The Base Layer already has animations set up. These are for Idle, Walk, and Run, as well as the jump animations. The orange block is something called a Blend Tree. It's worth double-clicking on the orange block to see the Blend Tree. You'll see this:

The Blend Tree has three animations coming off it, Idle, Walk, and Run. If you wanted to change an animation, you could do it here. (You might want a different walk animation, for example.) Click the tiny circles under the Motion heading, outlined with a red square, in the image above. Then select any animation you download and set up.

But go back to the Base Layer by clicking the link at the top.

Let's add a new Layer. We'll put our attack animation on this new layer. So, click the plus symbol to the right of the Layers tab:

Name the layer SwordAttack:

You should see three blocks in the main area, Any State, Entry, and Exit (you might have to scroll to see them all).

Right-click in the main area. From the menu that appears, select Create State > Empty:

You should now have this:

Now click on the Parameters tab at the top. You should see a few parameters already set up:

Parameters are values that you refer to in your code. For example, the Jump parameter has been set up as a Boolean. If this is set to true, then play the jump animation.

To add a new parameter, click the plus symbol indicated by a red arrow in the image above. You should see a dropdown list:

Select the Bool type to add a new parameter. Now type a new name for your parameter. Call it Attack. (You can call your parameters almost anything you like.) Take a note of the spelling here as you'll need the exact same text in your code.

We'll come back to this parameter soon. But we now need to drag a sword play animation into the main area, where the three blocks are. So, go back to your Eve animation in the project area at the bottom of Unity, the one you've just downloaded and set up. Expand your FBX file by clicking the arrow:

Drag and drop the green triangle into the main area:

The animation block has the name mixamo_com. You can rename this. Click the block to select it. In the Inspector on the right, type a new name at the top. Call it anything you like. We'll call ours SwordAttack.

Now right click on the orange New State block. From the menu, select Make Transition:

When you select Make Transition, you'll see a white line appear where your mouse pointer is. Drag the white line onto the SwordAttack block:

Now right-click the SwordAttack block and do the same - right click, select Make Transition. This time, drag the white line to the New State block. You then have two lines:

Now click on the second of the white lines, the one going from New State to SwordAttack. It should turn blue:

Then take a look at the Inspector. We want to set up a condition for when we're transitioning from an empty state to the SwordAttack. So click on the plus symbol to the right of List is Empty:

When you click the plus button, you'll see a dropdown with the list of your parameters. Select the Attack one:

Now uncheck Has Exit Time just above the blue blocks.

 

The Animation Code

OK, we're done with setting up the animation. We need to hack another of the C# scripts that came with the third person controller. In the Project area at the bottom of Unity, locate the scripts folder which is in the folder StarterAssets > ThirdPersonController >Scripts. Locate the ThirdPersonController script:

Double-click the ThirdPersonController C# file to open it up in your editor.

Again, because we're using the Input System, we have this using line at the top:

using UnityEngine.InputSystem;

Notice that this script has lots of variables set up at the top of the code. In particular, notice this one:

private StarterAssetsInputs _input;

This is a private variable called _input. Its type is StarterAssetsInputs, which is that other C# file you were hacking, the one where you set up some attack code.

Just above that line, you'll see some animation IDs set up. These ones:

// animation IDs
private int _animIDSpeed;
private int _animIDGrounded;
private int _animIDJump;
private int _animIDFreeFall;
private int _animIDMotionSpeed;

Add your own here. Add this:

private int _animIDAttack;

Now scroll down until you find this method:

private void AssignAnimationIDs()
{

_animIDSpeed = Animator.StringToHash("Speed");
_animIDGrounded = Animator.StringToHash("Grounded");
_animIDJump = Animator.StringToHash("Jump");
_animIDFreeFall = Animator.StringToHash("FreeFall");
_animIDMotionSpeed = Animator.StringToHash("MotionSpeed");

}

All those names in double quotes are the parameters that were set on the Animator tab. They are being turned into integers. Add your own to this. Add this as the final line:

_animIDAttack = Animator.StringToHash("Attack");

Now add this method (add it after the Update method so you can find it more easily):

private void Attack() {

if (_hasAnimator){

if (_input.attack)
{

_animator.SetBool(_animIDAttack, true);

}

}

}

We check if there is an animator. If this is true, then we have this if statement:

if (_input.attack)
{

_animator.SetBool(_animIDAttack, true);

}

The _input variable is the Input System, remember, the one where we set up out attack to use the F key. We set up a Boolean variable called attack in the StarterAssetsInput code. The if statement checks if this is true - have we pressed the F key, in other words.

If that's true, then we execute this line:

_animator.SetBool(_animIDAttack, true);

We use SetBool on the animator variable. In between round brackets we first have that ID we set up, _animIDAttack. After a comma, we set the Boolean to true. This is enough to set our Attack Boolean parameter to true.

Now we need to call the Attack method. In the Update method add the call:

private void Update()
{

_hasAnimator = TryGetComponent(out _animator);
JumpAndGravity();
GroundedCheck();
Move();
Attack();

}

And that's it. Save your code and go back to Unity.

Play your game. Press the F key on your keyboard and you should see your animation play, as in the short video below:

 

We only set our attack to use the F key on the keyboard. If you wanted to, you could go back to the Input Action screen and add a binding for a button on a gamepad. You wouldn't need to hack the code again. The code is already set up now. Which is the beauty of the new input system - it makes it easy to set up controls for a wide range of different devices all in the same place.

<--Back to the Unity 3D Course Contents Page