Transforming the Character Controller via script

Applying Root Motion to your character might be a very practical and accurate way to animate it. However, every now and then, you might need to manually control one or two aspects of the character movement. Perhaps you only have an in-place animation to work with, or maybe you want the character's movement to be affected by other variables. In these cases, you will need to override the root motion via script.

To illustrate this issue, this recipe makes use of an animation clip for jumping, which originally moves the character only in the Y-axis. In order to make her move forward or backwards while jumping, we will learn how to access the character's velocity to inform the jump's direction via the script.

Transforming the Character Controller via script

Getting ready

For this recipe, we have prepared a Unity Package named Jumping, containing a basic scene that features an animated character. The package can be found inside the 1362_07_05 folder, along with the animation clip called Swat@rifle_jump.

How to do it...

To apply the Root Motion via script, please follow these steps:

  1. Create a new project and import the Jumping Unity Package. Then, from the Project view, open the mecanimPlayground level.
  2. Import the Swat@rifle_jump.fbx file to the project.
  3. We need to configure our animation clip. From the Project view, select the Swat@rifle_jump file.
  4. Activate the Rig section. Change Animation Type to Humanoid, and Avatar Definition to Create From this Model. Confirm this by clicking on Apply.
  5. Now, activate the Animations section. Select the rifle_jump clip (from the Clips list), click on the Clamp Range button to adjust the timeline, and check the Loop Time and Loop Pose options. Under Root Transform Rotation, check Bake Into Pose, and select Baked Upon (at Start) | Original. Under Root Transform Position (Y), leave Bake into Pose unchecked, and select Baked Upon (at Start) | Original. Under Root Transform Position (XZ), leave Bake Into Pose unchecked. Click on Apply to confirm the changes.
    How to do it...
  6. From the Hierarchy view, select the MsLaser character. Then, from the Animator component in the Inspector view, open the MainCharacter controller.
  7. From the top-left corner of the Animator view, activate the Parameters section, and use the + sign to create a new Parameters (Boolean) named Jump.
  8. Right-click on the gridded area and, from the context menu, select Create State | Empty. Change its name, from the Inspector view, to Jump.
    How to do it...
  9. Select the Jump state. Then, from the Inspector view, populate it with the rifle_jump Motion clip.
    How to do it...
  10. Find and right-click on the Any State. Then, selecting the Make Transition option, create a transition from Any State to Jump. Select the transition, uncheck Has Exit Time, and use the Jump variable as a condition (true).
  11. Now, create a transition from Jump to Move.
    How to do it...
  12. Configure the transitions between Jump and Move, leaving Has Exit Time checked, and use the Jump variable as a condition (false).
    How to do it...
  13. From the Hierarchy view, select the MsLaser character. Then, from the Inspector view, open the script from the BasicController component.
  14. Right before the Start() function, add the following code:
    public float jumpHeight = 3f;
    private float verticalSpeed = 0f;
    private float xVelocity = 0f;
    private float zVelocity = 0f;
  15. Inside the Update() function, find the line containing the following code:
    if(controller.isGrounded){

    And add the following lines immediatly after it:

    if (Input.GetKey (KeyCode.Space)) {
      anim.SetBool ("Jump", true);
      verticalSpeed = jumpHeight;
    }
  16. Finally, add a new function, following immediately before the final } of the code:
      void OnAnimatorMove(){
        Vector3 deltaPosition = anim.deltaPosition;
        if (controller.isGrounded) {
          xVelocity = controller.velocity.x;
          zVelocity = controller.velocity.z;
        } else {
          deltaPosition.x = xVelocity * Time.deltaTime;
          deltaPosition.z = zVelocity * Time.deltaTime;
          anim.SetBool ("Jump", false);
        }
        deltaPosition.y = verticalSpeed * Time.deltaTime;
        controller.Move (deltaPosition);
        verticalSpeed += Physics.gravity.y * Time.deltaTime;
        if ((controller.collisionFlags & CollisionFlags.Below) != 0) {
          verticalSpeed = 0;
        }
      }
  17. Save your script and play the scene. You will be able to jump around using the Space key. Observe how the character's velocity affects the direction of the jump.

How it works...

Observe that once this function is added to the script, the Apply Root Motion field, in the Animator component, changes from a checked box to Handled by Script. The reason is that in order to override the animation clip's original movement, we have placed, inside Unity's OnAnimatorMove() function, a series of commands to move our character controller while jumping. The line of code: controller.Move (deltaPosition); basically replaces the jump's direction from the original animation with the deltaPosition 3D Vector, which is made of the character's velocity at the instant before the jump (x and z-axis) and the calculation between the jumpHeight variable and gravity force overtime (y-axis).

..................Content has been hidden....................

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