Version: 2021.1
Root Motion - как оно работает
Blend Trees (Деревья смешивания)

Туториал: Скриптинг Root Motion для гуманоидных “in-place” анимаций.

Sometimes your animation comes as “in-place”, which means if you put it in a scene, it will not move the character that it’s on. In other words, the animation does not contain “root motion”. For this, we can modify root motion from script. To put everything together follow the steps below (note there are many variations of achieving the same result, this is just one recipe).

  • Откройте инспектор для FBX файла, который содержит “in-place” анимацию и перейдите во вкладку Animation.
  • Убедитесь что Muscle Definition назначен аватару, которым вы хотите управлять (допустим, этот аватар называется Dude, и он уже был добавлен в окне Hierarchy View).
  • Выберите анимацию из доступных клипов.
  • Убедитесь, что свойство Loop Pose выровнено (свет рядом с ним зеленый), и чекбокс для Loop Pose активен.
  • Предварительно осмотрите анимацию чтобы убедится в плавном выравнивании начала и конца анимации, и в том, что персонаж движется “на месте”.
  • create a curve позволит вам управлять скоростью персонажа (добавляется кривая в Animation Import инспектор Curves-> +)
  • Дайте кривой соответствующее имя, например “Runspeed”
  • Создайте новый Animator Controller, (назовем его, например, RootMotionController)
  • Назначьте ему нужную анимацию, создайте состояние с именем анимации (например, Run)
  • Добавьте контроллеру параметр с таким же именем, как у кривой (в нашем случае “Runspeed”)
  • Выберите персонажа Dude в Hierarchy, который уже должен иметь компонент Animator.
  • Перетяните RootMotionController в свойство аниматора Controller.
  • Теперь если вы нажмете Play, вы увидите как персонаж “Dude” бежит на месте.

И наконец, чтобы управлять движением, нам нужно создать скрипт (RootMotionScript.cs), который реализует OnAnimatorMove callback:-

using UnityEngine;
using System.Collections;

[RequireComponent(typeof(Animator))]
    
public class RootMotionScript : MonoBehaviour {
            
    void OnAnimatorMove()
    {
            Animator animator = GetComponent<Animator>(); 
                              
            if (animator)
            {
     Vector3 newPosition = transform.position;
               newPosition.z += animator.GetFloat("Runspeed") * Time.deltaTime; 
     transform.position = newPosition;
            }
    }
}


Вам нужно прикрепить RootMotionScript.cs к объекту “Dude”. Когда вы это сделаете, компонент Animator определит что у скрипта есть функция OnAnimatorMove и отобразит свойство Apply Root Motion как Handled by Script (Обрабатывается скриптом).

Root Motion - как оно работает
Blend Trees (Деревья смешивания)