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.
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
.
To apply the Root Motion via script, please follow these steps:
Jumping
Unity Package. Then, from the Project view, open the mecanimPlayground level.Swat@rifle_jump.fbx
file to the project.Jump
.Jump
.Start()
function, add the following code:public float jumpHeight = 3f; private float verticalSpeed = 0f; private float xVelocity = 0f; private float zVelocity = 0f;
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; }
}
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; } }
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).
18.117.148.177