首页 > Unity3D频道 > 【Unity3D研究院之游戏开发】 > Unity3D研究院之在项目中使用Unity4新Mecanim动画(五十三)
2013
04-16

Unity3D研究院之在项目中使用Unity4新Mecanim动画(五十三)

Unity4的Mecanim动画很早以前就有体验过,迟迟没有加到项目中有两个原因,今天写这篇博客来记录我在做的过程中遇到的一些问题。

1.以前的代码代码量比较多,修改起来动的地方太多了。

2.使用Mecanim动画,还得需要美术的动画做配合才行。

在3.x中播放动画的时候使用Play()或CrossFade(),直接播放动画 或淡入淡出播放动画。 

也可以使用队列播放,让动画形成一个队列。

 我举一个我现在项目的例子。主角攻击敌人是一套连招,连招一共分为4套动画。也就是当玩家连续按下4次攻击键时这四套动画是连续播放的,假如玩家只连续按下2次攻击,可能只会播放前两套动画。代码中你需要判断其中某个动画是否播放完毕,只有播放完毕才能继续播放下一个动画。

 

 

大家在仔细想想这个命题,我们可以把动画分成4中可能的队列,也只可能分为这几种队列。

站立动画- 》攻击动画0 -》站立动画

站立动画- 》攻击动画0 -》攻击动画1 -》站立动画

站立动画- 》攻击动画0 -》攻击动画1 -》攻击动画2-》站立动画

站立动画- 》攻击动画0 -》攻击动画1 -》攻击动画2-》攻击动画3-》站立动画

此时如果用unity3以前的动画方式,无非就是上面这几种方法加上一些逻辑判断完成。现在Unity4加入了Mecanim动画,可以很好的帮我们解决这个问题。详细的动画使用教程我就不多说了,网上已经有很多人写过了。

如下图所示,以前我们在使用模型的时候。一个原始模型,原始模型中没有动画。然后是动画模型,每一个动画都会依赖原始模型。动画的名称末尾用 名称 + @name来表示。 这样的做法使用起来非常方便,但是由于每一个动画都会依赖原始模型所以文件会非常大。

Unity3D研究院之在项目中使用Unity4新Mecanim动画(五十三) - 雨松MOMO程序研究院 - 1

 

Unity4已经将默认模型与动态导入的类型做了修改,你会发现你的模型拖拽入Hierarchy视图中没有Animation组件而是Animator组件。如果你还是想在Unity4中使用以前的动画系统。你需要把每个模型和动画的类型改成 Rig-> Animation Type -> Legacy,如下图所示。

Unity3D研究院之在项目中使用Unity4新Mecanim动画(五十三) - 雨松MOMO程序研究院 - 2

 

手动的改起来会非常的累。建议你将下面这条脚本放在项目Editor文件夹下(没有创建一个)。这样当你将模型或动画拖入Project视图中,程序会自动帮你修改它的类型,显然Unity已经不建议大家继续使用以前的动画系统了。

 

下面开始说说新的动画。在Animations选项卡中先勾掉Import Animation 点击Apply。如下图所示,在Rig选项卡中修改Animation Type的类型为Humanoid。 如果你希望现在选择的这个模型做为标准模型的话,在Avatar Definition中选择Create From This Model。点击下方的Configure可以预览你的骨骼。

Unity3D研究院之在项目中使用Unity4新Mecanim动画(五十三) - 雨松MOMO程序研究院 - 3

 

 

让美术修改一下以前的动画,将动画中的原始模型去掉,这样还可以减少文件的大小。然后在Porject视图中找一个原始模型拖拽入右侧Preview中,可以看到这个模型已经播放奔跑动画。

Unity3D研究院之在项目中使用Unity4新Mecanim动画(五十三) - 雨松MOMO程序研究院 - 4

 

 

此时换一个模型拖入同样可以预览奔跑效果。

Unity3D研究院之在项目中使用Unity4新Mecanim动画(五十三) - 雨松MOMO程序研究院 - 5

 

 

 

 

 

如下图所示,在动画的.fbx中 因为动画需要用刚刚生成的骨骼。所以这里Avatar Definition中你需要选择Copy From Other Avatar 。在Source中选择刚刚生成的Avatar 以后所有动画都需要这样来设置。。

Unity3D研究院之在项目中使用Unity4新Mecanim动画(五十三) - 雨松MOMO程序研究院 - 6

 

下面我们来让这个女模型和男模型共用男模型的那一套动画,在游戏视图中播放。在Project视图中选择Crate->AnimatorController。然后把Project中男模型和女模型都拖拽入Hierarchy视图中。 将刚刚创建的AnimatorController放置在Controller处。

Unity3D研究院之在项目中使用Unity4新Mecanim动画(五十三) - 雨松MOMO程序研究院 - 7

 

 

此时在Unity导航菜单栏中选择Window -》 Animator。 将动画文件拖入Animator窗口中,你会发现两个模型都开始发生运动。如下图所示,黄颜色表示它为原始动画,也就是根动画。用箭头将它们一一前后相连,箭头实际上就是动画播放的条件。请注意看图中两个蓝色的箭头,A播放完后将会播放B动画,可是B却对应了两个箭头,也就是说B播放完后可以播放C也可以回过头来播放A。

Unity3D研究院之在项目中使用Unity4新Mecanim动画(五十三) - 雨松MOMO程序研究院 - 8

 

那么B播放完到底是播放C还是播放A呢?用鼠标点击一下箭头,看看这这两个箭头的条件吧。分别点开BA 和BC的两个箭头,在右侧监测面板视图中你都会发现Conditions下有一个Exit Time的条件。根据动画的不同对应数值也会不同,我的数值是0.94。也就是当B动画播放0.94s后将播放下一个动画。默认BA和BC的动画时间是一样的,Unity会有限选择下一个动画,也就是A -》 B-》-》C-》D-》A这样循环播放下去。假设我现在需要动画是 A-》B-》A这样循环播放,只需要修改一下BA箭头的条件,将Exit Time改小一点只要比BC箭头上的小就可以。。 其它的播放虚列原理类似。。

 

Unity3D研究院之在项目中使用Unity4新Mecanim动画(五十三) - 雨松MOMO程序研究院 - 9

 

 

接着还有问题了,用时间来做动画切换的条件是不是有点太限制了。Animator还支持自定义条件,在Animator窗口的左下角处,点击“+”按钮就可以添加变量。这里我添加三组变量, float 、int、bool。 

Unity3D研究院之在项目中使用Unity4新Mecanim动画(五十三) - 雨松MOMO程序研究院 - 10

 

变量添加完毕后,继续点击箭头的条件,箭头上可以有一个条件 或者多个条件。如果是多个条件需要多个条件同时满足才可以。 Conditons左键是变量名称,中间是变量条件,右边是变量值。

Greater 表示左边变量大于右边时触发

Less 表示左边变量小于右边时触发

Equals 表示左边变量等于右边时触发

NotEquals表示左边变量不等于右边时触发。

int 变量上述四种都有,float变量只有Greater 和Less, bool变量只有true和false。

Unity3D研究院之在项目中使用Unity4新Mecanim动画(五十三) - 雨松MOMO程序研究院 - 11

 

此时我们在加深一下理解。选择AB的箭头,也就设置A动画切换B动画的条件。 

ft     Greater      5 表示 当ft的值大于5的时候触发。

it      Less           3 表示 当 it的值小于3的时候触发。

ib     true            表示 当ib的值等于true的时候触发。

只有上述三种条件全部达成时将A动画将切换播放B动画。否则将一直停留在播放A动画处。

Unity3D研究院之在项目中使用Unity4新Mecanim动画(五十三) - 雨松MOMO程序研究院 - 12

 

那么ft it ib的这三个变量到底在那里设置呢?如下图所示,才记得前面我们创建的三个变量吗? 这三个变量对应的值就是右边的 0.0 0 false 。在编辑器中你可以通过修改这三个数值来满足播放动画的条件。可是在代码中怎么办呢?

 

Unity3D研究院之在项目中使用Unity4新Mecanim动画(五十三) - 雨松MOMO程序研究院 - 13

 

 

在代码中你可以这样来设置或变更它们的条件。 如果说你需要在程序中判断当前动画的一些信息,可以使用 GetCurrentAnimatorStateInfo(0),我查了一下Animator不能直接拿到当前播放动画的名称, 只能拿到它对应的Has值,也就是说你需要将原始的动画名称转换成Hash来判断。

 

 

另外Mecanim还支持多个动画的混合。目前Mecanim还有一个最大的难题,也是文章最上面我说的需要美术配合的那部分。之前我们看到的动画都是应用于人型模型,也就是说它支持人形的骨骼, 举个例子我们的项目人和武器是两个骨骼,这样在用Mecanim就悲剧了。因为不同模型武器的骨骼不一样所以公用模型的话会出现武器位置不对的情况。最后我想到的办法就是美术将以前做的武器骨骼重新导出,每个人对应一套自己武器骨骼(或者一些特殊的骨骼)最后生成武器的动画 ,比如 站立动画、攻击动画、死亡动画等。当Mecanim播放动画的时候,同时在播放该模型对应的武器动画,我想这样就可以解决这个问题吧。。

最后欢迎大家一起讨论。。

 

今天有朋友QQ上问了我已下,是不是非人形动画还得使用老的动画系统?如下图所示,当你把模型导入Unity的时候,这里可以选择它的类型。

legacy:是老的动画系统,这里就多说了。

Generic:是新的动画系统,它就是支持非人形的动画,建议使用它。但是它不能向Humanoid重定向动画。

Humanoid:就是新的人形重定向动画系统。

Unity3D研究院之在项目中使用Unity4新Mecanim动画(五十三) - 雨松MOMO程序研究院 - 14

 

雨松MOMO提醒您:亲,如果您觉得本文不错,快快将这篇文章分享出去吧 。另外请点击网站顶部彩色广告或者捐赠支持本站发展,谢谢!

--

最后编辑:
作者:雨松MOMO
专注移动互联网,Unity3D游戏开发
捐 赠如果您愿意花10块钱请我喝一杯咖啡的话,请用手机扫描二维码即可通过支付宝直接向我捐款哦。

  1. “然后把Project中男模型和女模型都拖拽入Hierarchy视图中。 将刚刚创建的AnimatorController放置在Controller处”我想问一下如果Animator不拖入控件中,通过代码怎么实现,请大神帮帮,怎么解决。

    • private Animator animator;
      public AnimatorController controller;
      void Awake()
      {
      animator = this.GetComponent();
      animator.runtimeAnimatorController = controller;
      }

  2. 为什么我的执行 if(animatorState.IsName(“Base Layer.Run_FastStop_Idle”)) { Debug.Log(“动画相等”); }else { Debug.Log(“动画不等”); }一直是进入到else里边我动画的名字和核对过了没有错,为什么

  3. 我们项目的controller都是用动作库里的动画组合出来的,那如何在将单个动画单独打包成资源的情况下(直接打包controller序列会导致重复资源太多),动态的加载和使用controller?

  4. 你好~请问一下ModelImporter modelImporter = (ModelImporter) assetImporter; modelImporter.animationType = ModelImporterAnimationType.Legacy;这样改变动画类型之后好像没有效果 虽然界面显示的是Legacy类型但是还是要点Apply才生效 想代码执行Apply又没有,这个有什么办法解决吗?

  5. 你好,我想问问假如我想人物头部应用IK怎么办,我看它API上只有左右手脚,好像没办法设置头部的权值?然后假如我想在非人型的模型上执行IK的话需要怎么做?

  6. 大家请教一个问题我在做unity手机游戏开发的书上的案例做打僵尸的调用AnimatorStateInfo stateInfo = m_ani.GetCurrentAnimatorStateInfo(0);的时候提示Object reference not set to an instance of an object大家能给解答一下么?

    • Update里AnimatorStateInfo aniState = animator.GetCurrentAnimatorStateInfo(0);if (aniState.IsName (“Attack”)) { if (aniState.normalizedTime >= 0.5f) { …… }}

  7. 切换武器这块,如果能找到手上骨骼上面添加个武器物件 我觉得应该实现,可是可是,新版动画怎么获取骨骼呢 Animator.GetBoneTransform 这个传了所有参数返回都是空 但是avatar是有效的可以配置 无语了啊

  8. Pingback: viagra

  9. Pingback: Perlengkapan bayi

  10. MOMO老師您好,很佩服您在unity方面的研究,更佩服您的無私分享,小弟最近看您的文章開始學unity的mecanim系統,有一些事情想跟您請教,就是發現官方教學mecanim系統都用rigidbody而不是character controllor?我一直搞不懂為什麼,不知道MOMO老師可以幫忙解惑嗎?感謝

  11. Pingback: オークリー サングラス

  12. MOMO老师,我的现在的项目也用了Mecanim动画系统,但是新的动画系统不能像原来的Animation一样在某一帧添加Event了。比如说,我有一个攻击的动作,需要在第17帧的时候出现一个刀光特效啊。老的动画系统的话直接在某一帧调用一个生成特效的方法就好了,但是在新动画系统下这种Event的东西怎么实现呢?我一点思路都没有TAT

  13. 当我使用Any State进行条件触发切换动画的时候,如何判断一个动画已经完成了切换?如果我是想重置一个动画到初始帧(A动画切换到A动画)该怎么操作?因为我使用了Any State,我给每个动画设定了一个ActionIndex,条件分别为ActionIndex==1切换到A,2切换到B,我如果当前处于A触发了切换A的条件,怎么判断A动画切换到了A(也就是重置回第0帧)

    • 为什么没帧都都会切换动作?我有点不太明白。 AnimatorStateInfo animatorState = animator.GetCurrentAnimatorStateInfo(0); if(animatorState.IsName(“Base Layer.Run_FastStop_Idle”)){//在Update里面 这里就可以判断当前正在播放什么动画?}还是我理解的有误? 你可以加我QQ详细的讨论一下 289187120

    • 为什么没帧都都会切换动作?我有点不太明白。 AnimatorStateInfo animatorState = animator.GetCurrentAnimatorStateInfo(0); if(animatorState.IsName(“Base Layer.Run_FastStop_Idle”)){//在Update里面 这里就可以判断当前正在播放什么动画?}还是我理解的有误? 你可以加我QQ详细的讨论一下 289187120

      • 当前只能说是处于某种State. 正在播放的动画, 取决于前置状态或者后置状态是否是BlendTree, 如果是 BlendTree, 可能正在播放一种混合的动画.

  14. MOMO说的关于武器和人的动画问题。 我们以前动画都做在人身上而不是给武器单独做动画。否则匹配一定成问题。 (手上多加一根骨骼作为挂载点,武器导出时坐标要讲究下,这样你只需要控制创建哪一个武器在玩家手里。如果武器需要收起的话背上也可以加挂载点。) 你说的分开做动画,一般用在骑宠身上的。 不知道有没有帮助。非常谢谢你的教程在你这里学了好多。而且很好懂噢~~~~~符合我这种没基础的动画师

  15. Pingback: 情趣内裤

  16. Pingback: c字裤怎么穿

  17. Pingback: c字裤美女

  18. Pingback: 蕾丝内衣

  19. 最近我也在研究Mecanim,感觉坑太多了,各种不完善。暂时发现缺少一些API,例如楼上说的回调,过渡到同一个动画的不同帧,任意层之间状态sync… 只能各种workaround了

  20. Mecanim最大的好处是可以多个模型使用同一套动作大大提升效率,官方有个例子可以两百个模型流畅播放,如果每个角色的东西都比较特殊比如说待机 攻击都是特有的动作,Mecanim的优势不是很明显 除了动作融合比较方便和直观,最近在看这块Mecanim最大的问题是播放完成以后没有回调 即播放完一套攻击动作后 程序不知道已经播放完成,只能在update里面一直检查状态, 感觉效率比较低,不知道MOMO有没有好的解决方案~