Character Root Motion

Root motion is a technique to let an animation control the movement of a character, usually used temporarily when performing an ability that involves movement such as an attack where the character steps forward.

This is done by having a bone in the character's armature that has a translation track that moves the whole armature. The character movement component can use this translation to move the character. This will move the entire character actor including any physics collider so that it is able to detect collisions, move up and down slopes. When the animation is over, the player can continue controlling the character from its new position.

Using root motion

In order to setup a root motion animation we first need to do 2 things

  1. Setup the animation component with a root bone. The root bone is the bone that should have the translation animation and usually has no or very minor rotation.

  2. Wrap an AnimationClip with a RootMotionClip. This will provide information to the animation system for how to treat this animation.


// 1
const bone = this.characterMesh.getObjectByName("mixamorigSpine2") as Bone 
this.animation.setup(this.characterMesh, [], bone)
// 2
const rootMotionSlash = RootMotionClip.fromClip(attackClips.spinSlash, false)

To then play the animation when the character performs an ability such as an attack, roll, etc., you need to perform 2 things.

  1. Play the root motion clip created earlier.

    1. In Place - We also specify that this animation is not be be played "inPlace" as we want it to have full control of the character's animation.

    2. Loop - Set loop to false as the animation should automatically end after having been played once.

    3. Priority - This animation will override any existing animation playing such as animation controlled with an animation state machine by passing in a higher priority value.

  2. Set the root motion action on the character movement component by retrieving it from the character animation component. The movement will now let the animation control the desired movement and ignore any direction input from the player.

// 1
this.animation.play(rootMotionSlash, {
  inPlace: false, loop: false, priority: 1
})
// 2
this.movement.setRootMotionAction(this.animation.getRootMotionAction())

Last updated