标签归档:Mecanim

Unity3D中Mecanim动画切换与AnimationEvent的关系

在我们的游戏中,我们使用了Mecanim动画中的Generic动画类型,几乎所有的动画切换和融合,我们都直接交给Animator自行处理了。省事倒是省事了,随之也带来了一些不可预知(其实是自己能力不足好吧)的问题。

今天我要分享的是一个这样的问题,例如主角正在进行A动作,此时受到攻击通过Trigger设置,切换到B动作,主角的AnimatorController中并没有直接从A动作过渡到B动作的Transition,A动作和B动作都是可以从AnyState直接切换的,也就意味着AnimatorController会自动根据当前动画的状态从当前播放的动画过渡到目标动画中去。

在A动作还没有播放完的情况下,我们通过设置Trigger的方式将A动作切换到B动作,而A动作上又绑有一些AnimationEvent,这些AnimationEvent会在动画执行到对应的时间轴的时候触发回调,用图来表达,最好不过了。mecanim_transition_animation_event图一中的这种情况,OnSkillEnd这个AnimationEvent是不会被回调的,而在图二中,OnSkillEnd这个AnimationEvent就会被回调。因为每个从AnyState出发的Transition都是有过渡时间的,如果绑定的AnimationEvent所处的时间轴在动画过渡时间之内,那么就会触发这个Event,否则就不会回调。

如何让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

 

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

import setting

QQ20140816-6@2x

QQ20140816-7@2x

 

 

 

 

 

 

 

 

 

 

虽然大神帮我们解决了这个困扰了我将近4天的问题,那么究竟为啥捏?其实在被困扰的4天里头,其实也发现了一些蛛丝马迹的,就是每次我们导入动画[email protected]的时候,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,所以问题到这里就彻底明了了。