How to do it...

To use root motion for steering, follow these steps:

  1. Import your character with Idle, WalkForward, WalkLeft, and WalkRight root motion animations into Unity.
  2. Select the character asset file and go to the Inspector. Make sure the Animation Type is set properly for your character (Generic or Humanoid). If you are using a Generic character, make sure to set its Root Node.
  3. Go to the Animation tab and select the Idle animation. Select all the Bake Into Pose options and set the Base Upon option of the Root Transform Rotation to Original.
  4. For the WalkForward animation, select the same options as for the Idle animation, but uncheck Bake Into Pose for Root Transform Position (XZ).
  1. For the WalkLeft and WalkRight animations, set all the option the same as for the WalkForward animation, but additionally uncheck the Bake Into Pose option for Root Transform Rotation.
  2. Set the Loop Time options to true for these animations.
  3. If your animations don't loop perfectly, you can try out the Loop Pose option. It will force the start and end poses to loop.
  4. Apply the import settings.
  5. Place your character into a scene.
  6. Select it in the Hierarchy and add a Capsule Collider to it. You may need to adjust the Capsule Collider properties to better fit your character. In our examples, we need to set the Height property to 2 units and the Y axis in the Center property to 1 unit.
  7. Add a Rigidbody component to the character and set its Constraints to Freeze Rotation in every axis.
  8. Navigate to the Animator component of the character (it is added automatically for animated game objects). Set Update Mode to Animate Physics. Make sure the Apply Root Motion option is checked in the Animator component.
  9. Create an Animator Controller asset for the character.
  10. Drag and drop the Idle animation into the Animator Controller to make it the default state.
  11. Create float Speed and float Direction parameters in the Animator Controller.
  12. Right-click on the empty space in the Animator Controller and choose Create State | New From Blend Tree.
  13. Click on the Blend Tree and change its name in the Inspector to Steering.
  14. Double-click on the Blend Tree to open its settings.
  15. Click on the plus button and choose the Add Motion Field option three times.
  16. Set the Parameter of the Blend Tree to Direction; we will only use the Direction parameter for blending walk animations.
  17. Drag and drop the WalkLeft animation in the first (upper) field, the WalkForward in the second (middle) field, and WalkRight in the third (lower) field.
  18. Uncheck the Automate Thresholds option.
  19. Set the WalkLeft animation Threshold to -45, WalkForward animation Threshold to 0, and the WalkRight animation Threshold to 45.
  20. Double-click on the empty space in the Animator Controller to get out of the Blend Tree settings.
  1. Create two transitions:
    • Idle | Steering with the condition set to Speed parameter greater than 0.5, Has Exit Time set to false, and Transition Duration set to 0.2 seconds.
    • Steering | Idle with the condition set to Speed parameter less than 0.5, Has Exit Time set to false, and Transition Duration set to 0.2 seconds.
  2. Write a script to set the Speed and Direction parameters of our Animator Controller and assign that script to the character.
  3. You can find the script in the provided Unity project in the Scripts directory of this recipe. It is called RootMotionSteering.cs.
  4. In this script, we make the character move relative to the camera. In the Update() function, first we get and store player input in two variables, hor (for Horizontal input) and ver (for Vertical input):
       hor = Input.GetAxis("Horizontal"); 

       ver = Input.GetAxis("Vertical"); 
  1. As we want to move the character relative to the camera, we're using the camera's forward and right axis to build a desired movement vector. Our camera is not completely horizontal (it can face slightly down, for instance), so first we need to calculate cameraHorizontalForward by taking the normal camera forward vector, setting its Y axis to 0, and normalizing the vector (so it has a length of 1):
        cameraHorizontalForward = new 
        Vector3(cameraTransform.forward.x,
        0f, cameraTransform.forward.z).normalized; 
  1. In this script, cameraTransform is a public Transform variable to which we attach our in-game camera.
  2. Next we calculate the desiredMoveDirection: this is a vector pointing in the direction that we would like to move our character. This vector points directly to the right axis of the camera when the player holds the right arrow, to the left of the camera when player holds the left arrow, to the horizontal version of camera's forward axis (cameraForwardHorizontal) when the player holds the up arrow, and to the opposite direction of that vector when player holds the down arrow:
       desiredMoveDirection = ver * cameraHorizontalForward + hor *
       cameraTransform.right; 
  1. Next we calculate the angle between our character's forward vector and our desiredMoveDirection vector. We will use this value to set the Direction parameter in the Animator Controller. The Vector3.Angle() method returns an angle between two vectors. This angle is always positive (greater than 0). Therefore, we use the dot product of the desiredMoveDirection and transform.right (our character's right axis) vectors to determine whether the desiredMoveDirection points to the right or to the left of the character (the dot product is greater than 0 for vectors pointing in the same direction and less than 0 for vectors pointing in the opposite direction). We use the Mathf.Sign() method to make sure our dot product value equals -1 or 1. The result is an angle from -180 to 180 degrees; we store the value in the float direction variable:
         direction = Vector3.Angle(transform.forward,
         desiredMoveDirection) *
         Mathf.Sign(Vector3.Dot(desiredMoveDirection,
         transform.right)); 
  1. Then we calculate a float speed variable's value; it is simply the magnitude of our desiredMoveVector. The speed variable is used to set the Speed parameter in our Animator Controller:
        speed = desiredMoveDirection.magnitude; 
  1. Lastly, we use the calculated direction and speed values and set them in our Animator Controller, with a dampTime parameter of the SetFloat() method set to 0.2 seconds to smooth out the blends. The anim variable stores the reference to the Animator component of our character and is set in the Start() function:
       anim.SetFloat("Direction", direction, 0.2f, Time.deltaTime); 
       anim.SetFloat("Speed", speed, 0.2f, Time.deltaTime); 
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.12.166.131