今天我们来一起学习在Unity3D中如何实现角色攀爬效果。

    在RPG游戏中,某些游戏场景常常需要玩家沿着墙壁或者×××攀爬到高处,例如《仙剑奇侠传三》的九龙坡场景中,玩家需要沿着×××爬到高处才能收集场景中的物品,而在《古剑奇谭一》中的翻云寨,玩家则需要爬到顶层才能开启游戏里的机关。那么今天我们就来利用Mecanim动画系统中的MatchTarget来实现角色攀爬效果。在正式开始今天的内容前,首先让我们来了解下MatchTarget的具体概念。MatchTarger即匹配目标,是Animator类中的一个方法,该方法可以实现在执行动画的过程中使角色身体的某个部位与指定位置进行匹配,比如我们在攀爬的过程中,手、脚及身体应该是和墙壁接触的,那么这时我们就可以考虑使用这个方法,该方法定义如下:

[csharp] view plaincopyprint?

1.     void MatchTarget (Vector3 matchPosition, Quaternion matchRotation, AvatarTarget targetBodyPart, MatchTargetWeightMask weightMask,  

[csharp] view plaincopyprint?在CODE上查看代码片派生到我的代码片

更多精彩请到http://www.gopedu.com/


1.     float startNormalizedTime,float targetNormalizedTime)  

可以看出,在该方法中,我们指定了匹配的位置、角度、身体的具体部分、权重、匹配开始及匹配结束的时间。由此,我们就可以开始今天的内容了,首先我们来创建一个简单的场景:

wKiom1QRClaQT60VAAEsC-hUkTI424.jpg在这个场景中,我们希望角色可以沿着墙壁爬到墙上。那么具体怎么做呢?首先我们在场景中创建一个空的游戏体,将其命名为RightHandTarget,它将作为角色在攀爬时右手的一个匹配点,我们将其拖放到合适的位置,然后将其拖放到墙模型下,使其成为它的一个子物体。如图所示:wKiom1QRCnCQTWjwAACtDGdNkco473.jpg好了,这样我们完成了场景部分的搭建和准备工作,接下来我们来制作角色的动画模型,新建一个Animator Controller,命名为JumpGrab,双击打开Animator窗口,这里我们只拖入两个动画Idle'和JumpUp,这里我们新建两个float类型的参数MatchStart、MatchEnd及Bool类型的参数Jump,触发JumpUp动画的条件是Jump为True。如图wKioL1QRCp_jvmVGAAGM2Ku9jJc955.jpg

其中JumpUp是一个完整的攀爬墙壁的动画,在这个动画中,角色首先会伸出右手进行攀爬,因此我们可以将其右手与我们在场景中定义好的RightHandTarget进行匹配,从而保证角色在攀爬的过程中总是紧紧贴着墙壁。好了,现在让我们来编写脚本来将动画模型和角色关联起来:

[csharp] view plaincopyprint?在CODE上查看代码片派生到我的代码片

1.     using UnityEngine;  

2.     using System.Collections;  

3.       

4.     public class TargetMatching : MonoBehaviour  

5.     {  

6.         //动画组件  

7.         private Animator animator;  

8.         //右手着力点  

9.         public Transform RightHand;  

10.      //是否完成跳跃  

11.      bool hasJumped = false;  

12.    

13.      AnimatorStateInfo mState;  

14.    

15.      void Start ()   

16.      {  

17.          //获取动画组件  

18.          animator = GetComponent<Animator>();  

19.      }  

20.    

21.      void Update ()   

22.      {  

23.    

24.          if (animator)  

25.          {  

26.              //获取动画状态  

27.               mState = animator.GetCurrentAnimatorStateInfo(0);  

28.    

29.              if (Input.GetButton("Fire1")) animator.SetBool("Jump", true);  

30.              if (mState.IsName("Base Layer.JumpUp") || mState.IsName("Base Layer.FullJump"))   

31.              {  

32.                  animator.SetBool("Jump", false);  

33.                  //调用MatchTarget方法                 

34.                  animator.MatchTarget(RightHand.position, RightHand.rotation, AvatarTarget.RightHand, new MatchTargetWeightMask(new Vector3(1, 1, 1), 0), animator.GetFloat("MatchStart"), animator.GetFloat("MatchEnd"));  

35.                  hasJumped = true;  

36.              }  

37.          }  

38.        

39.      }  

40.  }  


   好了,下面我们来看最终的效果吧!

wKioL1QRCr-BYMgaAAHdSiDidA0555.gif