【Unity】RootMotion的实际应用大整理.
有机紫菜
编辑于 2025年12月09日 19:27

根动画,实际使用时候会遇到的问题.与解决方法.包括

  • RootMotion怎么播放好.

  • RootMotion的父级怎么同步动画偏移值.

  • RootMotion怎么脱离控制器播放动画.(灵魂出窍)

  • 怎么重置出窍后的位置---setLocalPosition.

需要了解的概念---RootMotion

  • 游戏开发中RootMotion与普通动画(非Root)的应用大概一共有3种主要状态,父级跟着动画走,父级不跟着动画走,原地踏步(普通动画).

  • 一种是,父级,碰撞器啥的,控制器,不跟随人物动画,"人物出窍动画"---适用于坐下凳子,上床睡觉啥的,有位移.

  • 一种是,跟随动画走.RootMotion,动画蹦到哪里,父级跟到哪里,比如做Boss跳跃攻击,打开RootMotion,跳跃攻击之后,可以关闭RootMotion,再用程序控制Boss位移.有位移

  • 还有一种是原地踏步,动画的位移被去掉了,也就是普通动画的效果.无位移

1.我想播放RootMotion动画,并让上面的碰撞体,跟着RootMotion动画变动,怎么设置?

  • 要先明白,Apply Root Motion的物体,只会控制动画Animator所在的物体的位置,如果Animator有父级物体比如角色容器,是带不动的.---也就是只会控制子物体的位移.

  • 打开Apply Root Motion,动画片段不勾选BakeIntoPose,就行了.

  • 如果你一个跳跃动画,准备使用RootMotion,带动控制器,则需要想办法,让父级跟着子一起动.就是下面的情况.

2.我想让父级跟着RootMotion动画中的Root变动信息变动,并且还不让子物体播放RootMotion动画怎么做?

通常情况,是子物体也就是带Animator的物体,Apply Root Motion并播放root动画,然后让父级跟着子物体的位置变动,也就是猫捉老鼠的情况,这种方式不太好,因为子一直在变,父级一直追,所以就诞生了下面的这种方法,子不变,父级直接变.

(适用与人物的特殊动画,比如坐下,躺沙发,或者各种交互,与某种浮空斩击之类的常用情况.)

  • 直接通过OnAnimatorMove()方法.读取其animator.delataPosition

注意,可以不打开Apply Root Motion而直接获取到这部分的偏移量,也就是说.直接用一个bool变量,控制啥时获取这部分偏移值,并将其设置给父物体的变化就行了.---下面的代码中rootAnim是一个bool变量,可以手动控制.

  • 直接用一个bool变量rootAnim,控制啥时获取这部分偏移值,并将其设置给父物体的变化就行了.

注意必须写在OnAnimatorMove()方法中.

注意.物理影响:如果你的父对象或子对象与Rigidbody相关联,父对象的位置更新可能会与物理模拟冲突。在这种情况下,应当使用Rigidbody的MovePosition方法或其他角色控制的移动方法.来更新位置,而不是直接修改Transform。

 myparent.transform.position += animator.deltaPosition;

myparent.transform..rotation *= animator.deltaRotation;

这里的deltaPosition它返回自上一帧以来由Animator组件的Root Motion引起的角色位置的变化量。换句话说,它表示了由于动画的Root Motion在当前帧中角色位置的改变。

OnAnimatorMove() 方法是一个虚方法,它可以在实现了 MonoBehaviour 的脚本中被重写。这个方法在Animator组件处理完动画的Root Motion之后,但在实际应用Root Motion之前被调用。

下面的方法不怎么常用.

我想让动画.播放位移动画的时候,比如坐下,人物有一个位移.碰撞体位置不变.应该怎么设置?

回答:有2种办法.

  • 一种是,动画灵魂出窍.动画控制人物位置,脱离了控制器.

    • 这种方式,如果你要想,恢复人物位置,直接播放一个Idle的动画就行了,

    • 再加入一个Root恢复位置的方法,setLocalPosition.

  • 一种是,程序控制XY方向的位移(程序读取动画XY轴的变化),动画只是播放,动画,无位移操作.---程序读取一个动画XY方向的变化.---上面的方法2

  • 还有一种是,动画父级位置,实时的跟着RootMotion.这时候,玩家的碰撞体.需要关闭.

当人物Root后脱离了原来的位置后.恢复之前的位置---

注意,必须是LocalPosition.

      transform.localPosition = Vector3.zero;

      transform.localRotation = Quaternion.identity;   

灵魂出窍的设置

要实现,灵魂出窍(人物脱离自身的碰撞体积).就要勾选.Bake into Pose

原地播放动画

不打开动画片段的BakeIntoPose,XZ.---原地播放前进动画

其他

其他需要了解的

  • Body transform:动画发生的位移和旋转,只是单纯的动画效果,不会影响模型自身在世界空间中的实际位置和朝向。

  • Root transform:动画发生的位移和旋转,会改变模型实际的位置和旋转。

  • Bake into Pose实际上就是“烘焙成姿势”,姿势将是子物体的实时运动,不会影响父物体的位置和方向。

  • Root的中心,是算出来的,物体的质量中心在水平平面的投影位置(重心投影).如果想要设置成脚.Based Upon模式,和Feet模式的区别.

  • 注意Generic动画,如果想要开启RootMotion则需要,在导入设置里面,选一个骨骼作为根骨骼.一般是选Hips

使用时候的一些问题

  • 应该使用哪种RootMotion形式,

  • 2种形式,都可以做到,人物脱离控制器,与同步控制器.

    • TimeLine+Bake Into Pose

    • Animator的Apply Root Motion---不推荐.---改用下面的实用方法2.

    • Animator的Mask,给上半身动画.上半身的操作,比如按钮,啥的.人物不锁定.---只有很少的一些情况,会坐在座位里面,---触发某种事件.锁定.

  • 不同的RM形式,对应的情况.

  • 这些都是针对,实时游戏内容来讲的.

  • 比如一个人物,上车,或者上马,上摩托,原来的人物碰撞体怎么办.

  • 原来的人物可以隐藏,摄像机,fade到新的控制物上,比如车或者马.

  • 人物上车可以用Root动画或者TimeLine动画,播放完上车后(上车后,创建一个假人物体,可以是SpawnAmesh,继承当前人物的坐标.原来的人物以因为Rootbake自动返回原来的位置.),人物的整个物体隐藏,--打开汽车的操作控制器.

  • 一个人物上座位,或者床上躺着,原来的碰撞体怎么办.

  • 动画,过场当中,人物的碰撞体怎么办?

按照使用情况分类

  • 特别小的动画,比如人物按一个场景中的大按钮.---无锁定模式.人物播放动画,+IK混合---似乎需要Point辅助.

  • 中小型动画,比如坐下凳子,上床,单杠,等一些需要RootMotion的.使用TimeLine的系统,或直接在Animator中,设置Root.或上面的方法2.

  • 中型的.---比如上马,上车,这些则需要单独配置.比如上面的方法2.加确定播放后,物体的坐标.

  • 中大型的---比如场景动画.则需要场景TimeLine---加控制不同的人物.

其中通用的功能和技术

  • 人物转身,或者是,MoveTo,目标地点,目标的朝向.----人物主体的位置.

  • 人物的手部分,脚部分的IK目标.---把手和脚,放到目标位置.---四肢的动作.

  • 人物的,操作控制,关闭,与开启.---人物的控制开关.

  • 人物的IK部分,渐变的过程,和Animation混合的流程.---四肢的细微动作

  • 拿武器时候,特殊的,手部IK,与武器的IK,比如一个武器一直托在地上.