纳金网

标题: 有关游戏角色控制的几种实现方式 [打印本页]

作者: wyb314    时间: 2012-10-24 09:31
标题: 有关游戏角色控制的几种实现方式
       在3D游戏中,角色是不可或缺的一部分。用户的输入决定了主角的大部分输入,比如按下鼠标的向上的方向键,你可能发现主角向前移动了一段距离,并且同时播放了行走的动画。那么我们该如何很好的控制我们的主角呢?
     我看了很多官方的Demo,发现了一个很大的共同点:只要是人物角色,几乎都加入了CharacterController( 角色控制器 )。这个很关键,因为角色控制器封装了很多了不起的功能,比如:人物角色与墙体发生碰撞时自动停下来,可以想真人一样的上斜坡等。那么我们怎样利用角色控制器来很好的控制人物角色的运动呢?
    我们首先进入官网的一个资源比较集中的页面,下载一个官方的工程,链接为:http://unity3d.com/support/resources/example-projects/character-animation。然后解压并用Unity来打开。

    里面有四个场景:goober,Cross fade,Mixing - Cross fade,WalkRunIdleBlend这四个场景。我们先打开第一个场景goober。如下图:file:///C:/Documents%20and%20Settings/Administrator/Local%20Settings/Application%20Data/youdao/ynote/images/FB3E9A8BF9AC43548B35AFE56ABE6E81/52c8b8a6c9584f5d930615178c87f018.jpg





映入眼帘的是一个很奇怪的小人,我叫他goober。单击“运行”按钮,左手试着按下方向键,你会发现小人在不断的移动,甚至可以走上台阶。按下空格键,那个goober还会跳起来,甚至可以跳到台阶上。兴奋之余,我们也该干一下我们的正事了,那就是分析代码。我发现这个goober场景中也没有什么代码,摄像机上绑定了一个SmoothFollow脚本,goober上绑定了一个SuperMarioController与SuperMarioAnimation脚本。我们重点研究SuperMarioController脚本。这个脚本对于初学者来说,尤其是对那些向量运算不熟的人来说,有一定的难度,但总体来说比较简单。我们先复制其代码的前一部分file:///C:/Documents%20and%20Settings/Administrator/Local%20Settings/Application%20Data/youdao/ynote/images/6B763BE0B6944679B3C07C8A14802CD0/5c5ad1b947c249079a3a80760f826eac.jpg






我们在研究别人的代码时,决不能按部就班,从上到下来看,一定要灵活的进行切换,比如,我们先看Awake函数中的类容后看前面声明的变量。我们从Awake函数中看到,moveDirection的结果为goober的自身Z轴的方向单位向量(一定要熟悉API),而且我们知道了moveDirection是一个三维向量,且从字面上看这个三维向量的最后可能成为goober的移动方向。下面我来给下面的一段代码截个图。





















我们再往下读,发现有一个UpdateSmoothedMovementDirection这个方法,顾名思义,是为了更新刚才的那个moveDirection这个三维向量的,那么这个方法又是在哪里调用的呢?哦,原来是在Update函数的第一行就被调用了,那么这个函数也会在每帧执行。
      此函数的第一行定义了一个变量cameraTransform用来存储主摄像机的transform,第二行定义了一个变量forward用来存储此摄像机自身的Z轴方向的方向单位向量。然后将forward的世界Y轴分量消除,并将其规范化(即让此向量的长度变为1,方向不变)。第39行定义了一个向量right,其值很特殊,为:Vector3(  forward.z,0,-forward.x )。不难发现,如果将forward与right相乘,你会发现其值刚好等于0.那么这两个单位向量垂直,而且由于forward的值是由摄像机决定的。如下图:








file:///C:/Documents%20and%20Settings/Administrator/Local%20Settings/Application%20Data/youdao/ynote/images/681CD7CCF224459BA1339FD73939E04A/afb25f3f9bc44a86bf63429ef1c2e5b6.jpg
然后我们看下一句:
var targetDirection = Input.GetAxis( "Horizontal" )*right +Input.GetAxis( "Vertical" )*forward ;
定义一个变量用来存储水平按键轴的偏移量乘以right向量与垂直方向轴偏移量乘以forward向量的合向量。这好像是在利用方向键来构建一个方向。继续看下面的代码,我们基本上已经明白了,确实是跟我们想象的很一致。这个函数就是用来构造goober的面朝方向的。期间用到了线性插值运算。

    我们现在可以看Update函数了,首先更新moveDirection的值。还是截个图看看吧。file:///C:/Documents%20and%20Settings/Administrator/Local%20Settings/Application%20Data/youdao/ynote/images/0AC58EC4C8504CFF820F456D326BEC5A/830d160b84954846bc03a06b44f33e44.jpg




我们看第80行,我们发现,此movement是由刚才更新的moveDirection来决定的。然后乘以了Time.deltaTime来时这个速度与秒来挂钩。然后再84行取得goober的CharacterController组件,最关键的一句代码终于出现了,那就是CharacterController组件中的一个方法:Move( v : Vector3 ),这个方法时角色控制器的一个非常重要的方法另一个方法为SimpleMove,详情请看API文档。然后再第89行来为goober指定一个旋转四元数,此四元数作用于goober,goober的自身Z轴方向向量与moveDirection相同,这就是第89行的作用。这里我要强调一句,一定要熟悉那些比较常用的类中的API函数,不然是看不懂代码的。

至此,我们看到goober角色控制方面的代码就看完了,剩下的那几句代码比较简单,留给读者自己去思考吧。此控制方案的基本思路是由摄像机出发的。由于摄像机的用的是官方的SmoothFollow脚本,且其target为goober,则此摄像机的总是Z轴对准goober的。然后将此Z轴向量给提取出来,消除Y轴方向分量以使其与世界XZ轴所形成的平面平行,我们将此向量取名为forward。然后构造一个与forward垂直的向量right,利用这两个向量与两个按键轴的偏移量分别对应相乘初步定位了goober的移动方向。剩下的事情也就简单多了。此为一种角色的控制方式。是利用角色控制器来控制角色的一种很重要的方法。这个工程文件夹中还有几个场景,里面用的角色的控制方法与goober相比要简单一些,这里就不便多说了,下一篇我来介绍另外一种方法,使用刚体组件与胶囊体来控制角色的运动。
   
作者: 艾西格亚    时间: 2012-10-24 11:16
感谢分享!
作者: .    时间: 2012-10-25 21:08
顶起
作者: 比巴卜    时间: 2012-10-26 09:19

作者: 冰点    时间: 2012-10-26 09:34





欢迎光临 纳金网 (http://c-www.narkii.com/club/) Powered by Discuz! X2.5