月度归档:2014年08月

如何让 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 动画系统骨骼动画问题解决方法

这几天开始做游戏中跟动画相关的部分了,此次新项目我们决定一次从新开始,就是能用新的东西就都用新的东西,没有必要总是把自己局限在之前的认知里头,所以此次我们大胆而又现实的采用了 Unity 4.x 版本新增的 Mecanim 动画系统,并且我们果断地又选择了使用 Humanoid 动画类型。好吧,一切从新开始。

一切从新开始就意味着会有很多新的坑需要自己一个个去填,我们一直都拥有一颗坚强受虐的心不是吗。在我们的动画设计师将骨骼动画调好了之后,给了我一组 FBX 文件,导入 Unity 之后,预览一下这个动画吧。

animation-1

animation-2

 

 

 

 

 

 

我们可以很明显得看出这两个动画中人物角色的右手和武器之间的位置关系是不对的,跟动画设计师在 3DS Max 中制作和预览的效果也不对,好吧,碰到第一个坑,上吧。

通常我们先做的第一件事情就是先查查文档,看看 Unity 官方是否有一些最佳实践的建议,可是我翻遍了 Unity Manual 中关于 Mecanim Animation System 的所有文档没有看到相关的内容,而游戏引擎通常对于开发者来说就是个黑盒,出了问题除了查查看看别人是否碰到同样的问题也就是直接找 Support 这条路了,或者就是自己各种尝试呗。好吧,那就先 Google 一下吧,找啊找,找啊找,找了将近两天看了很多跟 Mecanim 动画相关的问题,但是就是没有找到这个这么基础的问题相关的帖子啥的,简直没有天理啊。

既然 Humanoid 不行,那我们试试 Generic 动画吧,这下就都 OK 了,那么显然动画资源自身肯定木有问题了,这下就确定肯定是 Unity 按照 Humanoid 动画导入 FBX 资源的时候有某些设置我们没有按照要求来做,所以导致了这个武器完全不跟着右手骨骼运动的情况。自己纠结了又一天,又是各种查啊各种试,完全木有进展。最后,只能求助于其他有经验的人了,通过我们的动画设计师,找到了一个他一个做技术美术的朋友,该大牛对 Unity 非常熟悉,专门解决项目中碰到的技术问题,哪里有问题哪里就有他。直接远程协助一下,看着大神一点点地调整,先是检查了一下 Avatar 设置中骨骼对应的关系是否正确,确认无误之后,再次运行看看效果依然如此,大牛稍微思考了一下,马上打开了 Unity 导入动画的页面,找到了 Animations 标签页,然后展开 Mask 设置中的 Transform 节点,将所有未勾选的人物角色骨骼节点都勾选上,然后 Apply 一下,再次运行游戏,搞定。

animation-3

animation-4

 

 

 

 

 

 

再回顾一下完整的调整过程吧,首先我们要确定我们出问题的骨骼具体是哪根,因为目前看到的现象是右手拿的刀和挂在腰上的刀鞘出现了问题,打开 Avatar 设置页面,查看一下,确定是 Bip001 Prop1 和 Bip001 Prop2 这两根骨骼出了问题。

Bip001 Prop1

 

确定了是这根骨骼出现问题了,然后进入到出现问题的动画文件 jin_wei_jun@run.FBX 的导入设置页面,打开 Animations 标签页 =》展开 Mask 节点 =》展开 Transform 子节点 =》找到左右手对应的刀和刀鞘的骨骼,勾选上,然后点击 Apply 按钮就好了:

import setting

QQ20140816-6@2x

QQ20140816-7@2x

 

 

 

 

 

 

 

 

 

 

虽然大神帮我们解决了这个困扰了我将近 4 天的问题,那么究竟为啥捏?其实在被困扰的 4 天里头,其实也发现了一些蛛丝马迹的,就是每次我们导入动画 jin_wei_jun@run.FBX 的时候,Unity 总会提示以下的警告:

MuscleClip ‘jin_wei_jun@run’ conversion warning: Bone position is different in avatar and animation
‘Bip001 L Thigh’ : position error = 31.473890 mm
‘Bip001 R Thigh’ : position error = 8.405679 mm
‘Bip001 L Clavicle’ : position error = 37.673038 mm
‘Bip001 R Clavicle’ : position error = 76.461647 mm

UnityEditor.DockArea:OnGUI()

和这样的一个警告:

MuscleClip ‘jin_wei_jun@run’ conversion warning: ‘Bip001/Bip001 Pelvis’ is between humanoid transforms and has rotation animation. This might lower retargeting quality.
MuscleClip ‘jin_wei_jun@run’conversion warning: ‘Bip001/Bip001 Pelvis/Bip001 Spine’ has translation animation. It is not supported.
MuscleClip ‘jin_wei_jun@run’ conversion warning: ‘Bip001/Bip001 Pelvis/Bip001 Spine’ is between humanoid transforms and has rotation animation. This might lower retargeting quality.
MuscleClip ‘jin_wei_jun@run’conversion warning: ‘Bip001/Bip001 Pelvis/Bip001 Spine/Bip001 L Thigh’ has translation animation. It is not supported.
MuscleClip ‘jin_wei_jun@run’conversion warning: ‘Bip001/Bip001 Pelvis/Bip001 Spine/Bip001 R Thigh’ has translation animation. It is not supported.
MuscleClip ‘jin_wei_jun@run’conversion warning: ‘Bip001/Bip001 Pelvis/Bip001 Spine/Bip001 Spine1/Bip001 Neck/Bip001 L Clavicle’ has translation animation. It is not supported.
MuscleClip ‘jin_wei_jun@run’conversion warning: ‘Bip001/Bip001 Pelvis/Bip001 Spine/Bip001 Spine1/Bip001 Neck/Bip001 R Clavicle’ has translation animation. It is not supported.

UnityEditor.DockArea:OnGUI()

这两个警告大体的意思是啥呢,刚开始自己没有太注意,后来总是找不到原因就想着会不会还就真是这俩警告给弄的呢,自己仔细看了一下。第一个警告的意思,应该说的是动画中有几个骨骼的位置跟这个动画实际使用的 Avatar 中骨骼的位置不相符,这个原因我大概能理解的原因是这样的。我们在制作的过程中会将模型文件和动画文件分开,我在导入模型文件的时候会创建一个属于这个模型的 Avatar,其他的动画都会直接引用这个 Avatar 文件而不会每个动画都创建自己的 Avatar,而不同的动画中人物可以会有一些不同的动作,这就会让动画中角色的一些骨骼位置和模型(模型默认姿态就是站姿)站立姿态时的骨骼的位置会出现一些不匹配的情况,所以这个可以理解了。那么第二个警告呢,这个警告都是说某根骨骼有位移动画和旋转动画,而这些动画会降低 Retargeting 的质量,同时 Humanoid 动画不支持在这些骨骼上使用位移动画。虽然这个警告中提到的带有位移和旋转动画的骨骼不少,但是涉及的就是角色躯干、胸部、臀部、左右手、左右脚这几个非常关键的骨骼,并没有提到影响到刀和刀鞘的骨骼 Bip001 Prop1 和 Bip001 Prop2 啊。

综合大神提供的解决方案,应该可以初步得出结论,导入 FBX 动画的时候,选择 Humanoid 动画类型进行导入的时候,Unity 会自行进行计算和判断,然后根据 Retargeting 最佳原则,设置 Animations 选项卡中 Mask 节点下 Transform 子节点中的骨骼是否需要在 Humanoid 动画中应用位移动画,而这个时候 Bip001 Prop1 和 Bip001 Prop2 这俩骨骼就被忽略了,所以我们需要手动的去勾选,如果有必要的话,那么就把所有的未勾选的骨骼都勾选上,然后再 Apply 一下吧,如果出现 Apply 一次不生效的话,重新重复设置遍,然后再 Apply 一下吧(我自己碰到了一次把所有的都勾选,然后 Apply 之后无效,重新展开之后发现只有部分被勾选上了,重新再全勾选 Apply 一次才好的情况)。

刚才我们提到了使用 Generic 动画的时候就不会出现这个问题对吧,那么为了印证这个结论是否正确,我们可以检查一下 Generic 动画导入设置页面中 Animations 标签页中 Mask 节点下 Transform 子节点中的骨骼节点是神马情况就好了。如下图,所有的节点默认都是勾选上的。

QQ20140816-10@2x

鉴于此,我们可以得出结论就是,在我们使用 Humanoid 动画类型导入 FBX 文件时,Unity 会以最佳匹配 Retargeting 规则的方式自行计算,看看那些骨骼是需要勾选 Transform 动画选项的,而默认使用 Generic 动画就会将所有的骨骼节点 Transform 动画选项都勾选上,所以效果是正确的。OK,所以问题到这里就彻底明了了。