How to do it...

To use root motion for off-mesh links, follow these steps:

  1. Import the character with Idle, WalkLeft, WalkForward, WalkRight, and JumpOffMesh animations.
  2. Create a new Animator Controller.
  3. Right-click on the empty space of the controller and choose Create State | New From Blend Tree. We need two such states. Name one of them Idle and the second one Steering.
  4. Create two float parameters in the controller, Speed and Direction, and one bool parameter, JumpOffMesh.
  5. Create two transitions:
    • Idle | Steering with one condition: Speed parameter value greater than 0.5. Has Exit Time should be set to false and Transition Duration set to around 0.2 seconds.
    • Steering | Idle with one condition: Speed parameter value less than 0.5. Has Exit Time should be set to false and Transition Duration set to around 0.2 seconds.
  6. Set the Idle animation in the Idle state.
  7. Double-click on the Steering Blend Tree.
  8. Set the Parameter of the Blend Tree to Direction: we will only use the Direction parameter for blending walk animations.
  9. Drag and drop WalkLeft animation in the first (upper) field, WalkForward in the second (middle) field, and WalkRight in the third (lower) field.
  10. Uncheck the Automate Thresholds option.
  11. Set the WalkLeft animation threshold to -45, WalkForward animation Threshold to 0, and WalkRight animation Threshold to 45.
  12. Double-click on the empty space in the Animator Controller to get out of the Blend Tree settings.
  13. Drag and drop your JumpOffMesh animation into the controller.
  1. Create two transitions:
    • Any State | JumpOffMesh with one condition: JumpOffMesh parameter set to true. Has Exit Time should be set to false and Transition Duration set to around 0.2 seconds.
    • JumpOffMesh | Idle with no conditions. Has Exit Time should be set to true and TransitionDuration set to around 0.2 seconds.
  1. Close the Animator Controller.
  2. Put your character on the scene. Add a Rigidbody component to it and freeze its rotation. Add a Nav Mesh Agent component and a Capsule Collider component (make sure the Height and Center properties are set correctly for it). Attach the NavMeshAgentWithRigidBody.cs script to the character.
  3. Add the ClickToMove.cs script to the character and assign its NavMesh Agent to the Agent field of the script.
  4. Create a new off-mesh link. To do so, create three Empty game objects and name them Link, Start, and End. Add the OffMeshLink component to the Link object. Drag and drop the Start game object into the Start field of the OffMeshLink component and the End game object to the End field of the component (see the following image). Bake the NavMesh (your ground game object has to have a collider and has to be set to NavMesh Static in the Navigation window, Object tab).
Off Mesh Link placement and baked NavMesh
  1. Uncheck the Auto Traverse Off Mesh Link option in the Nav Mesh Agent component of the character.
  2. Create a new script and call it MathOffmeshLink.cs.
  1. In the Update() function of the script, we first save the current animator state info to a currentAnimState variable. Then we check if our agent is on an off mesh link. If so, we set the JumpOffMesh bool parameter in the controller to play the JumpOffMesh animation. Then we calculate the targetPosition of our character by using the agent's off mesh link end position. Next we calculate the targetRotation of our character:
        currentAnimState = anim.GetCurrentAnimatorStateInfo(0); 
        if (agent.isOnOffMeshLink) 
        { 
             anim.SetBool("JumpOffMesh", true); 
             targetPos = agent.currentOffMeshLinkData.endPos; 
             targetDirection = targetPos - transform.position; 
             targetDirection.y = 0f; 
             targetRot = 
             Quaternion.LookRotation(targetDirection); 
        } 
                
  1. Next we check if our character is playing the JumpOffMesh animation. If so, we turn our Rigidbody component to kinematic (to disable collisions and gravity) and we use the MatchTarget() function on the Animator component. This function stretches the animation to match the target position and rotation. We set our targetBodyPart to the character's root. We set the startNormalizedTime and endNormalizedTime parameters to 0.25 and 0.75, respectively, because we transition to and from the animation and it takes some time, so we shouldn't start the target matching from the very beginning and we should stop it a bit earlier. You may need to adjust those settings in your particular case.
  2. Our script has also a public void CompleteOffMeshLink() function. It is called by an Animation Event from the JumpOffMesh animation. This function call the CompleteOffMeshLink() function on the Nav Mesh Agent component. That tells the component that we've finished handling the off mesh link traversing. Our event also sets the JumpOffMesh bool parameter in the controller to false (that prevents our character from jumping again) and turns the rigid body physics back on:
         agent.CompleteOffMeshLink()
anim.SetBool("JumpOffMesh", false); rb.isKinematic = false;
  1. Our rb variable is set in the Start() function and holds the reference to the Rigidbody component. The agent variable is also set when the game starts and holds the reference to our Nav Mesh Agent component.
  2. Assign the script to the character.
  3. Add an event few frames before the end of the JumpOffMesh animation and choose the CompleteOffMeshLink() function in it. Refer to the Using triggers to grab an edge while jumping recipe, step 16, if needed.
  4. Play the game and try to traverse the chasm to see the effect.
..................Content has been hidden....................

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