My journey becoming a Unity game developer: 2.5D Infinite Runner-Idle, Running, and Running Jump animations Pt.2
Objective: Setup the Idle and Running animation transitions to one another. Also, have the player animations rotate in both directions when they’re moving.
To start we want to have transitions go from Idle->Running, and from Running->Idle. Next, we need a Parameter to have the Player go from Idle->Running. Under the Parameter tab, click the “+” sign, and create a FLOAT parameter name Speed with its value set to zero.
Select the transition arrow going from Idle->Running, and turn off Has Exit Time as we want the animations to blend in from one to the other without waiting for the 1st animation to finish playing before going into the next one. We can turn off the Fixed Duration, set the Transition Duration and Transition Offset to zero if we want the Player animating from Idle->Running right away. Or we can leave Fixed Duration turned on with the Transition Duration set to the preset .25 value to give the Player a little blend time from one animation to the other. In Conditions, add Speed is Greater Than 0.1 value to say if the Player moves they will instantly go from Idle to Running.
For the Running->Idle transition, turn off Has Exit Time, set the Duration to however you want your animations to perform, and set the Conditions Speed to Less Than 0.1 value.
In the Player script, we need to move the horizontalInput variable to the Z-axis in the direction variable to make our Player move forward.
When we play the game, we see the Player animating moving forward, but sliding backward when we move the Player in the reverse direction. This is happening because when the Player moves in the reverse direction there is conflict happening between the Player’s animation returning back to Idle which is Less Than 0.1 and the Player moving with Negative values going in the reverse direction.
To fix this problem we will use the Animator’s anim variable to get the SetFloat() method to get the Speed condition. Then we will set the Speed using the Mathf.Abs() function passing in the Player’s direction along the Z-axis. This will move the Player in a direction along the Z-axis in a range of: 1=forward, 0=Idle, 1=reverse. As we can see their will be no negative numbers being returned as Mathf.Abs() will return the Absolute number value results.
Now when we play the game, we see the Player animations playing as they move forward and in reverse. When they stop, the Player will go into its Idle animation. However, if we look at the Idle and Running animations as they play, we can see the Player character is moving in weird directions as we play. This is happening because the Root Motion attached to each animation is moving according to its presets created with its Animation Rig.
Select the Idle animation from the Animations folder, go to Root Transform Rotation and turn on Bake into Pose. Do the same with Root Transform Position(Y-axis) and Root Transform Position(XZ-axis) Baking in their Pose if you see your character’s animation moving weird.
We will now flip the Player character to face in the direction they will be moving in. We will do this by rotating the Player using Local Euler Angles. The rotation of Euler angles is in degrees relative to the parent transform’s rotation. When using the Euler Angles property to set a rotation, you are providing the X, Y, and Z rotation values to describe our rotation. However, those values are not stored in the rotation, but instead the X, Y, and Z values are converted to the Quaternion’s internal format.
Inside the Player’s Transform, let’s look at the Y-axis which the player will rotate around. We can see when the Player is facing the forward direction at a value of zero, and when facing in the reverse position the value is 180.
Inside the Player script under the Update() function, we will check IF the horizontalInput is not equal to zero. If it’s not, create a new Vector 3 variable name facing to be set to the local Euler Angles of the Transform. With the facing variable, we will get the Y rotation and check IF the direction on the Z-axis is greater than zero. If it’s TRUE, the Player will stay rotated at zero degrees facing the forward direction. If FALSE, the Player will be rotated 180 degrees to face the reverse direction. Finally, we will set the Player’s Transform local Euler Angles to the facing variable’s new rotation according to which condition is met.
We used the ternary conditional operator to evaluate a Boolean expression and return the result of one of the two expressions, depending on whether the Boolean expression evaluates to true or false. It’s the same as using the IF condition, but an easier way of checking for 2 expressions.
Moving the Player, we can see in the Transform’s Rotation Y-axis going from zero to -180 degrees. The negative value has the Player rotating to face the left position, while zero value will have the Player rotating to face the right position. Remember we will see -180 degrees when the Player moves in the reverse direction, but inside Unity the system these values are converted into Quaternion rotation values which will be different.