如何让Unity3D Mecanim Generic动画支持动画中的位移

由于目前我们正在做的这个游戏中可能暂时还没有太强烈的需求去使用Mecanim动画系统中最新的Humanoid类型动画,我们首选的还会使用Generic动画,所以呢,前路漫漫其修远,大坑前面等你栽。 确定要使用Generic动画之后,那就继续呗。因为之前项目中使用的都是旧的动画系统(Legacy),所有角色和NPC的动画都是在原点做动作,角色和NPC在播放动画的同时需要通过脚本来控制角色的位移,这个要求负责程序和负责动画的童鞋密切合作把角色动画位移调整到一个协调的状态,这个当然也不是什么特别困难的事情,要不你看现在App Store里的所有游戏不都好好的嘛。 不过如果能让动画直接带上位移,那么程序和美术童鞋都解放了,动画设计的时候就能更大胆了,毕竟角色动画的真实位移相对于程序控制的更协调,而且大家都省了不少的事情,何乐不为啊。废话说了一大堆,好吧,回到正题。 那就做一个连续的带位移的动画吧,导入Unity之后,创建Animator Controller之后,把动作设置好,点击Play按钮,看看效果吧。尼玛,发现单个动画在播放的过程中角色确实发生位移了,但是每个动画结束之后回到IDLE状态动画的时候,角色在场景中的位置会发生一次闪回,直接重新归位到动画开始播放时角色所在的位置,并且在整个动画播放的过程中,角色的位置从未发生过变化,角色身上绑的Capsule Collider也完全不会移动,完全落在角色身后了。这是啥问题呢?这个问题在我使用Humanoid动画的时候木有出现啊,尝试再次恢复到Humanoid动画类型,确认了在Humanoid动画类型下确实不会出现这个位移闪回的问题,每个动画结束后,角色所在的位置就是动画结束时位置。 Mecanim-Generic-Rig-Apply-Root-Motion-Error 搜索良久最终找到了解决方法,其实只需要在导入动画的时候指定好动画骨骼的根节点就OK了。  

Generic-FBX-Import-Rig-Setting Humanoid-FBX-Import-Rig-Setting

 

 

 

 

 

咱们对比一下这两个设置的选项,其中Humanoid动画类型导入时,根本就不需要设置Rig的根节点,而Generic动画就需要设置,而且默认设置是none,所以需要手动指定为模型对应骨骼的根节点。

看来Unity动画支持Apply Root Motion这个特性的实现机制就是根据骨骼在动画中的位移在引擎内进行计算滴,如果我们选择使用Humanoid动画的话呢,肯定需要设置一个人形的骨骼Avatar信息,这个Avatar信息中就会包含骨骼各个节点的信息,其中当然也包含了根节点(或者说已经不需要根节点了,因为所有关键的骨骼信息都会映射到Avatar信息上)。而对于Generic动画呢,Unity自身并不清楚骨骼之间的关系,而Apply Root Motion这个特性就是根据骨骼位移自行计算的,那么就需要我们手动地指定动画使用的骨骼的根节点了,根据根节点在动画中的位置变化就可以动态计算出来对象在场景中实时的位置了。

下图就是修改Root Node设置之后动画播放时的效果了,Capsule Collider也实时跟着动画的播放改变位置了。

Generic-Apply-Root-Motion-1 Generic-Apply-Root-Motion-2

 

 

 

 

 

 

============== 更新于 2015-01-13 11:56:41 ==============

另外,所有Mecanim的Generic动画都会有一个依赖的Avatar Definition信息(不知道是不是翻译成蒙皮信息),在这个Avatar中指定指定Root node就好了。

在跟我们的动画设计师沟通之后,发现其实在3DS MAX中制作的动画都会自动生成一个Bip001 Footsteps的骨骼节点,该节点直接绑在Bip001根节点上,在3DS MAX中预览动画播放的全程中,这个节点一直都是Bip001节点在水平面上的投影,也就意味着这个点一直只在水平面上移动,是非常适合用来做Root Motion应用的Root node的,但是在将动画导入到Unity中之后,我们再查看Bip001 Footsteps这个节点的位移和在3DS MAX中并不一样,并不是一直处于模型质心的正下方,所以目前还无法使用Bip001 Footsteps这个节点作为Root Motion要使用的Root node,只能选择Bip001这个节点。

在我们通过设置Animator.applyRootMotion字段为True以及对动画依赖的Avatar Definition设置合适的Root node之后,动画在播放的过程中,会自动调整播放该动画的GameObject的Transform的位置信息(仅限X和Z轴)。那么在这个过程中我们能否再通过其他的方法,例如Rigidbody.MovePosition和Transform.position等方法来调整GameObject的Position呢?显然是可以的,在Animator应用Root Motion调整GameObject的Position同时,我们也可以通过其他的方法调整GameObject的Position,效果是叠加的。

如何让Unity3D Mecanim Generic动画支持动画中的位移》有4个想法

  1. Pingback引用通告: Unity3D中useGravity和isKinematic以及applyRootMotion的备忘 | 7dot9 Laputa

    1. 古拉是头猪 文章作者

      目前我们的项目中没有使用Bip001 Footsteps,这是因为我在测试中发现,如果角色被击倒在地,此时角色骨骼的Bip001 Footsteps节点可能并不是在质心正下方,还跟角色的双脚保持一个相对位置,此时就可能出现位置不正确的情况。

      回复

回复 Ansen 取消回复

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据