In the previous recipe, we've added a stop animation for a better transition to the idle state.
We can add even more animations to our movement to make it more accurate and responsive. An example of such animation is a 180-degree turn.
Getting ready
Use the same character as in the previous recipe. Add a 180-degree turn animation, starting with the Idle pose and ending with the Idle pose rotated by 180 degrees in the vertical axis.
Name the animation 180Turn for clarity. You can open the provided example Unity project and go to the Chapter 04 Character movement\Recipe 05 Using root motion for a 180 degrees turn directory. You will find an Example.unity scene there. Play the game and try to walk in the direction opposite to the one the character is facing (press the down arrow). You can find the Humanoid.fbx asset in the Rigs directory with all the required animations.
How to do it…
To make a 180-degree turn, follow these steps:
Create four transitions (see the following screenshot):
1.
Drag and drop your 180Turn animation into the Animator Controller to create a 2. new state.
Open the Animator Controller (this should be the same controller as in the 3. previous recipe), add two float parameters, and call them DirectionRaw
and SpeedRaw.
Check the Bake Into Pose option for the Root Transform Position (Y) in 4. the 180Turn animation.
In the Animation Import Settings of the character, find your additional 180Turn 5. animation. You may need to add it as a new clip by clicking on the plus button in
the Clips section (Animations tab) and choosing the 180Turn animation as the source.
Import the character and repeat all the steps from the Using root motion to steer a 6. character and Using animations for better looking transitions recipes to have a
character that is able to walk.
Idle | 180Turn with two conditions: The SpeedRaw parameter should be greater than 0.5 and the DirectionRaw parameter should be greater than 160. Has Exit Time should be set to false
and Transition Duration should be set to around 0.1 seconds.
Idle | 180Turn (a second one) with two conditions: The SpeedRaw parameter should be greater than 0.5 and the DirectionRaw parameter should be less than -160. Has Exit Time should be set to false
and Transition Duration set to around 0.1 seconds. We have two transitions between the same states because we want them to work as a
logical OR operator; if any of them is met, the transition will be triggered.
180Turn | Idle with one condition: Speed parameter less than 0.5. Has Exit Time should be set to true and Transition Duration set to around 0.1 seconds.
180Turn | Steering with one condition: Speed parameter greater than 0.5. Has Exit Time should be set to true and Transition Duration set to around 0.1 seconds.
Animator Controller with additional 180Turn transition animation
Edit the Idle | Steering transition by adding two more conditions: DirectionRaw 7. parameter greater than -160 and DirectionRaw parameter less than 160. Multiple
conditions in the same transition work as an AND logical operator; all of them have to be met to trigger the transition.
The Animator Controller is set up, but we need to set the SpeedRaw
8. and DirectionRaw parameters from scripts. We've created those two additional parameters because we need raw values here (not damped in time). First, open the script in which we calculate and set the direction and speed parameters. In this example, it is called RootMotionSteering.cs; you can find it in
the Chapter 04 Character movement\Recipe 03 Using root motion to steer a character\Scripts directory.
We have two float variables there: direction and speed. They are being 9. calculated every frame. We just need to make them public to be able to read
them in another script (they are already public in the example script).
Write another script and call it SetRawDirectionAndSpeed.cs (you can find it 10. in the Scripts directory of this recipe). To set the DirectionRaw and SpeedRaw
parameters, we use the following lines in the Update() function:
anim.SetFloat("DirectionRaw", steeringScript.direction);
anim.SetFloat("SpeedRaw", steeringScript.speed);
In the preceding lines, the anim variable is the reference to the Animator 11. component, the steeringScript variable is the reference to
the RootMotionScript component (we set it with the steeringScript = GetComponent<RootMotionSteering>() line in the Start() function), and the steeringScript.direction and steeringScript.speed variables are the calculated raw direction and speed values.
Alternatively, you can call the anim.SetFloat("DirectionRaw", direction) and anim.SetFloat("SpeedRaw", speed) methods directly in the Update() function of the RootMotionSteering.cs script (without writing another script).
Assign the script to the character, play the game, and try to walk in the direction 12. opposite to the direction the character is facing. The character should start with
an 180Turn animation first.
How it works…
This recipe adds a start animation that works as a transition between the Idle and Steering states. We use the SpeedRaw and DirectionRaw parameters to check the raw player input (not damped). Using damped values wouldn't work in this case because the
damped Direction parameter always starts from 0 and increases in time to the raw input direction value. This would always trigger the Idle | Steering transition before the Idle
| 180Turn transition as the Idle | 180Turn transition checks if the direction is greater than 160 or less than -160 degrees.
There's more…
To make it simple, this recipe shows just one case of a start animation: the 180 degrees turn.
You may require more start animations (-90 and +90 degrees turn or even -45, +45, -270, and +270 turns). You may also need to add a 180 degree turn transition from walking/running to make the character react to the input faster. In such a case, you may need to use Animation Curves to determine the walk/run position
(LeftPassing, RightPassing, LeftExtreme, RightExtreme) and play an appropriate turn animation accordingly (starting with
the LeftPassing, RightPassing, LeftExtreme, or RightExtreme pose).