Turn off root motion for a specific animation

Hi Guys!

I’ve had this question for a while now, but I can never seem to find an answer. Is there a way to turn off root motion for a specific animation? I know you can turn off root motion for an entire character (animator.applyRootMotion = false), but can you turn off root motion for just one animation?

For example, I’m prototyping a 3rd person combat game, and I use root motion for walking, running etc. But I don’t like the root motion that comes with the attack animations I have, and I don’t want the character to move while attacking. I’d rather his feet just slide on the floor and his transform stay the same place.

In the inspector, they have to option of “Bake root transform position (XZ) into pose”, but that doesn’t seem to work. While the animation is player, the character will still step off his transform spot while playing the animation. Then after the animation is played, the transform moves to where the character now is. It effectively does nothing.

Thanks for the help guys. This has been bugging me for for a while. There has to be a check box to turn off root animation on a per animation basis.

I think I’ve found the solution, which lies in the Animator function “ApplyBuiltinRootMotion”. Since writing a custom “OnAnimatorMove” will control your root motion by script, you can then do a test for the animation states that you want to apply root motion to. Here’s a simple example, where I’m only applying root motion to my TurnToLeft state:

// Callback for processing animation movements for modifying root motion.
void OnAnimatorMove()
{
    Animator anim = GetComponent<Animator>();
    AnimatorStateInfo stateInfo = anim.GetCurrentAnimatorStateInfo(0);

    // APPLY DEFAULT ROOT MOTION, ONLY WHEN IN THESE ANIMATION STATES
    if (stateInfo.fullPathHash == Animator.StringToHash("Base.Grounded.TurnToLeft"))
    {
        anim.ApplyBuiltinRootMotion();
    }
}

SIDE NOTE: If you’re using an animator on a child object of a main parent container object, root motion may move your parent and child away from each other. In that case, check out this solution: http://forum.unity3d.com/threads/getting-mecanim-root-motion-translation.241312/#post-1710537
This would be used in place of anim.ApplyBuiltinRootMotion(). Using that code and its “anim.deltaPosition.x” and “anim.deltaPosition.y” etc, is also helpful if you only want to ever apply root motion on one axis (like a sidescroller). If your char is going through walls, use charControllerRef.Move(newPosition); rather than changing the transform directly with those delta values.

It’s working for me!

This script was written to solve the exact issue described, that is, wanting root motion on all animations except attack animations :

Animator _animator;
AnimatorStateInfo _stateInfo;

void Awake () {
	_animator = this.gameObject.GetComponent<Animator> ();
}

void OnAnimatorMove () {
	_stateInfo = _animator.GetCurrentAnimatorStateInfo (0);
	if (!_stateInfo.IsTag ("Attack")) {
		
		_animator.ApplyBuiltinRootMotion ();
	}
}

Note: you will obviously have to tag all animations as “Attack” in the animator for this to work. To do this, simply click the animator, click on the specific animation state, and under the animations name you should see the entry spot for tag in the inspector. I hope this helps anyone else with a similar problem.

You can cheat, perhaps. I’ve not confirmed, I’m guessing.
Using GCAS in conjunction with .IsName(“StateName”) you can detect the animation in question.

Draw some techniques from this page, which details adding root motion to in-place animation, using OnAnimatorMove() function.

Detect the Root motion velocity. I can’t help with this step, never tried it. But I know its possible as its listed in the Animation preview.

Negate this velocity by adding the inverse.

Perhaps there is an easier way, like temporarily applying 0 velocity to the rigidbody, in any case, GCAS will help you.

but how to have root motion only while attacking and script motion while movement