邱竟峰 王洪源 陈慕羿
(沈阳理工大学 信息科学与工程学院,辽宁 沈阳 110159)
Unity3D引擎实现游戏人物的基本操控
邱竟峰 王洪源 陈慕羿
(沈阳理工大学 信息科学与工程学院,辽宁 沈阳 110159)
Unity3D作为一款更加专注作品的快速实现和平台推广以及3D渲染效果的游戏开发引擎,跟随移动平台和Web平台的迅速发展,抢占了大量市场份额。Unity3D不止限于单机平台,还可以借助Photon等游戏引擎,实现Unity3D单机游戏的网络化。本文所涉及的内容,就是使用Unity3D实现游戏中人物基本行为的控制。碰撞体 (Collider) 与刚体 (Rigidbody) 结合使用可以实现 Unity 中的物理特性。刚体 (Rigidbody) 使对象可以受物理控制,而碰撞体(Collider) 使对象可以相互碰撞。Animator可以将编辑动画的控制,管理不同动画之间的关联。
Unity3D;游戏人物控制;人物攻击
我们将事先准备好的游戏人物模型拖拽到Project的Assets文件夹下,然后将人物的静止状态模型拖入场景中。
然后在人物脚下Create Cube作为地面,取消Mesh Renderer选项,并给人物加上Rigidbody(注意Constrains中的Rotation选项,这会使物体碰撞后产生自由旋转)以及Capsule Collider。以实现人物的正常移动,调节胶囊碰撞器参数,使其包裹人物。
下面,我们使用编辑脚本实现人物的移动的控制。
在脚本中,使用float H=Input. GetAxis(“Horizontal”),实行对人物水平方向移动的监听,当在键盘上按下A或者D键时,会返回正或者负数值,以此值判断人物的左右的移动方向。 float V=Input.GetAxis(“Vertical”)与前者类似,不过是通过W和S键判断人物的前后移动。我们将它们放在update函式中,这样系统每针都会不停的监听人物的移动变化。我们使用if (Mathf.Abs(H) > 0.01f || Mathf.Abs(V)> 0.01f)来判断人物是否移动,如果移动,赋予人物速度,控制人物面向方向,GetComponent<Rigidbody>(). velocity = new Vector3(velocity * h, this. GetComponent<Rigidbody>().velocity.y,velocity* v),此处,我们利用之前为人物添加的刚体组件,实现人物的速度控制,因为人物是在水平方向移动,所以使用this.GetComponent<Rigidbody>(). velocity.y,作为Y轴速度,也就是Y轴速度不变。使用transform.LookAt(new Vector3(h,0,v) + transform.position)实现人物面向方向的改变。接下来,我们在Assets下Create一个Animator Controller,并把它添加到人物的Animator中,作为人物播放的动画控制器。
在Window中打开Animator,将导入的人物站立和移动的动画拖拽到里面,使用bool值控制两者的转换,实现站立(Take0010)向跑步动画(Take001)的转换时,我们将bool设置为true,当由跑步转换为站立时,设置为false。我们将anim.SetBool(“Move”, true)放在前面提到的判断语句后(这里,anim是Animator对象)就是当键盘控制人物移动时,将人物状态有站立设置为奔跑。当人物静止时,我们要实现人物的速度归零,并由奔跑转为静止状态。因此,在if后面添加else语句,并添加GetComponent<Rigidbody>(). velocity = new Vector3(0, this.Get Component<Rigidbody>(), 0) 与anim. SetBool(“Move”, false)前者实现速度归零后者设置人物状态为站立。如图1所示。
接着,我们调整摄像机位置,使摄像机跟随人物移动。选择合适视角,选中Main Camera,选择Game Object下的 Align With View,使摄像机与当前视野保持一致。然后将人物的Tag设置为Player并为摄像机添加控制脚本,使用 Game Object. Find Game Object With Tag(“Player”)找到跟随的人物,用transform.position设置摄像机的跟随位置。
因为一些攻击动画是有一连串的攻击实现的,所以这里我们先实现攻击
添加完成后会在原动画后面出现拆分后的动画。
完成拆分后,选择Animator ,添加新Layer,覆盖之前实现人物站立、跑动的Layer,并添加一个Empty State(处于EmtyState时,之前设定的人物站立于跑动的效果就会起作用),然后将拆分的两个动画拖入到Animator中,使用Trigger作为3个状态之间的转换方式。这里没有使用之前的Bool是因为,一旦使用Bool值作为转换条件,当触发第一次攻击时,Boll设置为True,那么第二个攻击效果就会自动出现,失去了拆分的意义。由攻击效果转换为Empty时,不需要额外设置,当攻击结束时会自动转换为Empty。如图3所示。动画的拆分。首先选中攻击模型,右侧Inspector中点击Edit。这里我们使用的攻击效果由两个攻击动作完成,所以我们将动画拆成两部分,点击加号根据第一个动画完成的时间,在Start和End位置添加参数,动画确定后,点击Apply。如图2所示。
这里还有一点要注意,在设置动作之间的转换时间的时候要注意选择合适的时间间隔,使当连续触发时,能够实现连击的效果。我们还是用脚本控制人物的攻击。在新的脚本中,首先在start()中调用this. Get Component<Animator>()获得加在人物身上的Animator。然后,这里我们添加简单的条件判断,实现动作的触发。在update中添加if (Input. GetKey(“space”)),这样,每帧都会进行按键检测。如果检测到按下按键,则调用之前在Animator中设置的SetTrigger(“Attack”)方法,这里Attack就是之前设置的Trriger参数的名字。
同时我们也可以为攻击添加声音效果,可以选择直接把声音添加在特效上,选中特效,点击Add Component,选择Audio Source,将想要加入的音效拖入到Audio Clip中。
我们也可以在脚本中添加音效,首先,Creat Empty,再为它添加Audio Source,新建音效控制脚本,在脚本中获得Audio Source对象,然后调用Audio Source. Play One Shot(Sound Name)即可。这里我们可以把控制脚本设计成单例模式,本例中,声音控制脚本命名为sManager,首先定义sManager对象instance,然后在Awake()中为其赋值:instance=this。这样做的好处是使得instance成为sManager在系统中的唯一实例,节省了时间和资源。
[1]王洪源,等. Unity3D人工智能编程精粹[M].北京:清华大学出版社,2014.
[2]金玺曾. Unity3D手机游戏开发[M].北京:清华大学出版社,2013.
TP311
A