查看: 6366|回复: 9
打印 上一主题 下一主题

[教程] Mecanim动画系统的Mask使用技巧

[复制链接]

955

主题

164

听众

7万

积分

版主

Rank: 7Rank: 7Rank: 7

纳金币
59338
精华
28

活跃会员 荣誉管理 突出贡献 优秀版主 论坛元老

跳转到指定楼层
楼主
发表于 2014-10-6 17:40:08 |只看该作者 |倒序浏览

Unity 4发布了Mecanim动画系统后,有不少的朋友仍然没有放弃3.5.x的版本,其中的一个原因4.x版本的默认是无法判断模型导入的动作,需要手动更改为Legacy才能正确的进行动作的播放。而另一个原因是,不明白Mecanim的动画管理有何优势,对于这点,我们将以一个简单的案例来说明Mecanim的妙用之处。

场景里面是一个导入的角色模型,采用了Humanoid 的动作类型,如果角色动作不打算套用在其他的模型上面,则采用Generic的类型即可,而选择Legacy的话就表示采用3.5.x版本的动作模式。

1.JPG

打开角色的Animation Controller,在Base Layer的动画层里已经设置了角色前后与左右移动,现在的问题是,如果我们需要在角色移动的同时叠加另一个动作,例如角色一边跑,一边做武器的更换,或是做装填子弹的动作,而武器的更换与子弹装填是另外的动作,那么应该如何设置呢?

2.JPG

按下+号新增一个动画层,将这个层命名为Layer2Weight是动画层的权重,Mask则是接下来需要自行建立的部分。

3.JPG

Project目录下新增一个Avatar Mask,名称自行定义即可,然后在Mask里面指定这个新增的Avatar Mask

4.JPG 7.JPG

双击打开Avatar Mask,里面是一个人形的图示,绿色的部分表示该关节位置允许叠加到Base Layer,而我们现在需要的是手臂的动作来执行武器的更换与子弹装填,所以必须关闭不需要的关节位置。

5.JPG

如图所示,点击不需要的关节位置使其成为红色状态即可,这样就能让此动画层仅有手臂的动作会叠加到Base Layer

6.JPG

接着在Layer2里面新增一个New State与两个Blend Tree, 我们需要将武器的更换与子弹装填的动作添加到这两个Blend Tree

8.JPG

如图所示,将两个Blend Tree更换名称并指定动作后,在Parameters里面新增两个Bool,分别命名为ReloadingSwitchWeapon,再使用Make TransitionNew State与两个Blend Tree进行连接。

9.JPG

New StateReloadingSwitchWeapon的连接采用了True,表示脚本里面所设置的按键按下后立即将false切换到true的执行状态。

10.JPG

ReloadingSwitchWeapon回到New State的连接采用了默认的Exit Time,分别设置为0.40.8的数值,这里的作用是让Layer2的动作回到New State时能有一个融合的效果。

11.JPG

Animation ControllerMask设置完成后,将以下的脚本添加到角色上面即可进行动作的测试,在角色移动的同时按下左键可执行一边跑步一边填充子弹,按下右键则是执行更换武器的动作。

角色代码使用的如下:
  1. using UnityEngine;
  2. using System.Collections;

  3. // 自动添加角色需要的组件
  4. [RequireComponent(typeof (Animator))]
  5. [RequireComponent(typeof (CapsuleCollider))]
  6. [RequireComponent(typeof (Rigidbody))]
  7. public class PlayerControlScript : MonoBehaviour
  8. {
  9.         [System.NonSerialized]                                       
  10.         public float meshMoveSpeed = 4.0f;
  11.         
  12.         [System.NonSerialized]
  13.         public float animSpeed = 1.5f;                                
  14.         
  15.         private Animator anim;                                                      
  16.         private AnimatorStateInfo currentBaseState;                        
  17.         private AnimatorStateInfo layer2CurrentState;        

  18.         static int reloadState = Animator.StringToHash("Layer2.Reload");                              
  19.         static int switchWeaponState = Animator.StringToHash("Layer2.WeaponSwap");
  20.         

  21.         void Start ()
  22.         {
  23.                 anim = GetComponent<Animator>();                                                                                 
  24.                 if(anim.layerCount ==2)
  25.                         anim.SetLayerWeight(1, 1);
  26.         }
  27.         
  28.         void OnAnimatorMove()
  29.         {
  30.                 if(anim)
  31.                 {
  32.                         Vector3 newPosition = transform.position;
  33.                         newPosition.z += anim.GetFloat("Speed")* meshMoveSpeed * Time.deltaTime;
  34.                         newPosition.x += anim.GetFloat("Direction") * meshMoveSpeed * Time.deltaTime;
  35.                         transform.position = newPosition;
  36.                 }
  37.         }
  38.         
  39.         
  40.         void FixedUpdate ()
  41.         {
  42.                 float h = Input.GetAxis("Horizontal");                                
  43.                 float v = Input.GetAxis("Vertical");                              
  44.                 anim.SetFloat("Speed", v);                                                      
  45.                 anim.SetFloat("Direction", h);                                                
  46.                 anim.speed = animSpeed;                                                              
  47.                 //anim.SetLookAtWeight(lookWeight);                                      
  48.                 currentBaseState = anim.GetCurrentAnimatorStateInfo(0);      
  49.                
  50.                 //Controls the movement speed
  51.                 if(v <= 0.0f)
  52.                 {
  53.                         meshMoveSpeed = 4;        
  54.                 }
  55.                 else
  56.                 {
  57.                         meshMoveSpeed = 6;
  58.                 }
  59.                
  60.                 if(anim.layerCount ==2)
  61.                 {
  62.                         layer2CurrentState = anim.GetCurrentAnimatorStateInfo(1);      
  63.                 }
  64.                
  65.                 if(Input.GetButtonDown("Fire1"))
  66.                 {
  67.                         anim.SetBool("Reloading", true);
  68.                 }
  69.                 else
  70.                 {
  71.                         anim.SetBool("Reloading", false);
  72.                 }
  73.               
  74.                 if (layer2CurrentState.nameHash != reloadState || currentBaseState.nameHash != switchWeaponState)
  75.                 {
  76.                         if(Input.GetButtonUp("Fire2"))
  77.                         {
  78.                                 anim.SetBool("SwitchWeapon", true);
  79.                         }
  80.                 }
  81.                 if (layer2CurrentState.nameHash == switchWeaponState)
  82.                 {
  83.                         anim.SetBool("SwitchWeapon", false);
  84.                 }
  85.         }
  86. }
复制代码
分享到: QQ好友和群QQ好友和群 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
转播转播0 分享淘帖0 收藏收藏0 支持支持0 反对反对0
回复

使用道具 举报

3

主题

1

听众

6189

积分

高级设计师

Rank: 6Rank: 6

纳金币
370
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

沙发
发表于 2014-10-6 18:19:55 |只看该作者
很不错的教程,有DEMO就更好了
回复

使用道具 举报

heise    

4

主题

3

听众

4249

积分

中级设计师

Rank: 5Rank: 5

纳金币
105
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

板凳
发表于 2014-10-6 19:51:22 |只看该作者
hariboot 发表于 2014-10-6 18:19
很不错的教程,有DEMO就更好了

官方的动作教程里面使用到了这说的这个功能,动作混合功能还是很好用的!
回复

使用道具 举报

3

主题

1

听众

6189

积分

高级设计师

Rank: 6Rank: 6

纳金币
370
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

地板
发表于 2014-10-6 21:31:42 |只看该作者
heise 发表于 2014-10-6 19:51
官方的动作教程里面使用到了这说的这个功能,动作混合功能还是很好用的! ...

教程链接有吗?
回复

使用道具 举报

0

主题

2

听众

4092

积分

中级设计师

Rank: 5Rank: 5

纳金币
530
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

5#
发表于 2014-10-7 06:56:51 |只看该作者
Thanks for sharing
回复

使用道具 举报

hyui    

1

主题

2

听众

6671

积分

高级设计师

Rank: 6Rank: 6

纳金币
2715
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

6#
发表于 2014-10-9 16:43:54 |只看该作者
I remember this is from Digital Tutors isn't it?
回复

使用道具 举报

0

主题

3

听众

2200

积分

中级设计师

Rank: 5Rank: 5

纳金币
0
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

7#
发表于 2014-10-9 21:06:54 |只看该作者
新人学习了,谢谢分享
回复

使用道具 举报

17

主题

1

听众

464

积分

设计实习生

Rank: 2

纳金币
149
精华
0

最佳新人

8#
发表于 2014-11-22 09:55:28 |只看该作者
非常详细呀
回复

使用道具 举报

0

主题

2

听众

1346

积分

助理设计师

Rank: 4

纳金币
505
精华
0
9#
发表于 2014-11-22 14:48:33 |只看该作者
赞一个  谢谢指导 ! 学习了
- 代码真实用
回复

使用道具 举报

0

主题

1

听众

939

积分

初级设计师

Rank: 3Rank: 3

纳金币
330
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

10#
发表于 2015-1-21 16:18:33 |只看该作者
嗯,比较详细。现在正在学习动画系统
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

手机版|纳金网 ( 闽ICP备2021016425号-2/3

GMT+8, 2025-1-26 08:11 , Processed in 0.076449 second(s), 35 queries .

Powered by Discuz!-创意设计 X2.5

© 2008-2019 Narkii Inc.

回顶部