基于Unity 3D 酷跑游戏的设计与实现
2022-03-24李爱军
李爱军
(苏州职业大学计算机工程学院,苏州 215104)
0 引言
主要游戏方式便是酷跑。以一个成功的酷跑游戏《神庙逃亡》为例,我们可知酷跑类游戏的主要功能。玩家不能控制角色的移动速度,随着游戏时间的推移,角色移动的速度越来越快,玩家操作的时间越来越短,考验玩家的反应能力来达到增加游戏难度的目的。
1 游戏主要设计
1.1 游戏类型定位
游戏有很多种类,主要有策略游戏、动作游戏、竞速游戏、卡牌游戏、冒险游戏、体育游戏、休闲游戏、音乐游戏、模拟游戏、射击游戏等。
本游戏为酷跑游戏,应归为竞速游戏或休闲游戏。
1.2 运行环境
本游戏的运行环境为手机Android 6.0 及以上系统版本,它的优点是游戏界面非常简洁,且占用的内存资源少,操作起来很方便。
1.3 游戏玩法
本游戏主要靠滑动屏幕控制角色移动来操作游戏,控制角色躲避障碍拾取金币。游戏地图分为三个跑道,向左滑为向左跑道移动,向右滑为向右跑道移动,向上滑为跳跃,向下滑为滚动,当角色在空中时向下滑动可以使角色快速落地滚动。
1.4 游戏流程
玩家运行主程序进入游戏画面,出现开始菜单。开始菜单包含两个按钮,开始和退出。点击开始按钮,游戏开始运行,点击退出按钮,退出主程序。开始游戏后弹出暂停按钮,点击暂停按钮游戏暂停,出现暂停菜单。暂停菜单包含两个按钮,返回游戏和退出游戏。点击返回游戏,游戏继续;点击退出按钮,游戏退出。当游戏角色死亡时,出现结束菜单。结束菜单包含两个按钮,再次开始游戏和退出游戏。点击再次开始游戏,游戏重新开始;点击退出游戏,退出主程序。
1.5 开发技术
本游戏是采用3D 虚拟技术和游戏物理引擎进行开发的,游戏的现场布景具有很强的真实感、立体感以及逼真的光影效果,用户能够在游戏中感受到绚丽多彩且富有冲击感的感官体验。
2 游戏界面搭建
2.1 酷跑角色与场景搭建
2.1.1 酷跑角色与场景搭建
在Scene 界面通过导入模型,拖拽搭建等步骤完成场景的初步搭建。
2.1.2 金币组
将8个金币设为一组,布置在跑道上。
2.1.3 障碍物与碰撞监测器
障碍物有木板、小汽车、大巴,分别添加碰撞检测器。
2.1.4 道具
将道具模型导入,制作碰撞动画粒子特效。
2.1.5 游戏文本菜单
游戏菜单用来开始或退出游戏以控制游戏进程,右侧为道具buff 剩余时间,右下角为音乐控制按钮,左上角为收集的金币数。
2.2 游戏逻辑实现
2.2.1 道路设置
游戏只有一个游戏场景,为一条无限长的马路。通过交替移动两段足够长的道路实现“无限”道路的功能。
void Update(){
if(transform.position.z>floorOnRunning.transform.position.z+32)
{ RemoveItem(floorOnRunning);
Addtem(floor0nRunning);
floorOnRunning. transform. position=new Vector3(0,0,floorforsard.transform.position.z+32);
Game0bject temp=floorOnRunning;
floorOnRunning=floorForward;
floorForward=temp;}}
2.2.2 角色奔跑
作为一个酷跑类游戏,首先要让游戏主角跑起来,我们通过在主角的模型上挂载一个主角控制脚本来实现。主角的控制脚本名为PlayerController。
通过在z轴正方向给主角添加一个正值,使主角可以沿z 轴正方向匀速跑动。然后在y 轴负方向,也就是默认的地面方向添加正值,使主角可以稳定在地面上,不会违背物理常识。这里没有选用unity3d 自带的物理系统,因为其系统在应用时发生明显的错误效果,所以进行了变量的赋值使其实现较真实的物理效果。
游戏主角以默认速度奔跑:
moveDirection.z=speed;
moveDirection.y-=gravity*Time.deltaTime;
characterController.Move((xDirection*10+moveDirection)*Time.deltaTime);
酷跑类游戏在游戏过程中会通过缓慢增加主角的奔跑速度来减少躲避障碍物的反应时间,从而起到加大游戏难度的效果。本游戏中主角每奔跑一段固定长度的路程时增加一点奔跑速度,同时为了防止某些实力过于强的玩家在游戏中长时间不失败导致的主角奔跑速度过高,游戏中还为主角的奔跑速度设置了最大值,使其速度不能无限制增长。
限制游戏主角的最大奔跑速度:
private void SetSpeed(float newSpeed)
{ if(newSpeed <=maxSpeed)
speed=newSpeed;
else
speed=maxSpeed; }
2.2.3 滑动检测
本游戏的操作非常简单,用指针在屏幕上进行上下左右的滑动即可控住主角的移动,一共设置了4个操作检测,分别为“向上”“向下”“向左”“向右”。
首先创建一个枚举类来存放上下左右空5种滑动状态。
滑动方向枚举类:
public enum InputDirection
{ NULL,
Left,
Right,
Up,
Down }
当玩家没有触摸屏幕时,屏幕没有检测到指针,滑动状态默认为空值,即游戏主角以默认速度匀速奔跑。当玩家向上滑动屏幕时,屏幕检测到指针,将状态更新为“开始滑动”并记录当前的指针位置。
当指针以某一个反向持续滑动20个单位时,记录此位置与开始滑动位置时的向量,并将其转化为角度,根据角度分析此次滑动的方向,同时将滑动状态更新为“未开始滑动”。
2.2.4 玩家移动
当游戏中检测到玩家的控制输入后,角色要根据控制指令进行相应的移动。当玩家向左滑动时,如果角色不在最左边的道路上,那么角色向左移动一格。当玩家向右滑动时,如果角色不在最右边的道路上,那么角色向右移动一格。
当玩家向上滑动时,角色进行一次跳跃。通过给角色y轴正方向添加正值来改变角色的竖直方向的位置。
当玩家向下滑动时,如果角色此时在地面上,那么角色进行一次翻滚,如果角色测试在跳跃中,那么角色迅速落到地面。与跳跃类似,通过给角色y轴负方向添加正值来改变角色在竖直方向的位置。
翻滚动作代码:
if(inputDirection==InputDirection.Down)
{ AnimationManager.instance.animationHandler=AnimationManager.instance.PlayRoll; }
当主角已经到达最左或最右的位置时不能再往左或往右移动,需要限制主角的移动以免跑出地图。
2.2.5 道具效果
本游戏一共设置了4种道具,分别为磁铁道具、加速道具、双倍积分道具和二连跳道具。
磁铁道具的效果为:角色自动吸取道路上的金币,持续一段时间。实现原理为,为角色添加一个大小等于磁铁作用范围的碰撞检测器,当碰撞检测器碰撞到金币时,触发金币的事件。拾取到磁铁道具时激活该碰撞检测器,持续时间结束时自动关闭。
二连跳道具效果为,玩家可以在跳跃过程中再次跳跃,当角色拾取到二连跳道具时,可以在道具持续时间内进行二次跳跃。
二连跳道具代码:
void JumpDouble()
{ AnimationManager.instance.animationHandler=AnimationManager.instance.PlayDoubleJump;
moveDirection.y+=jumpValue*1.3f; }
双倍积分道具的效果为:将拾取金币时获得的积分翻倍,持续一段时间。实现原理为:增加积分的数值。
加速道具的效果为:大幅度提升角色的速度,持续一段时间。实现原理:增加奔跑速度的数值。
2.2.6 相机跟随
本游戏为第三人称视角游戏,为了使角色始终处于画面中央,需要将显示游戏画面的相机对象设置为始终跟随角色移动,位置处于角色身后的斜上方。
相机跟随效果代码:
void LateUpdate()
{ if(!isShaking
&&GameController.instance.isPlay
&&!GameController.instance.isPause)
{ pos.x=target.transform.position.x;
pos.y=Mathf.Lerp(pos.y,target.transform.position.y+height,Time.deltaTime*5);
pos.z=target.transform.position.z-distance;
transform.position=pos; }
2.2.7 碰撞检测
碰撞检测是非常重要的功能,游戏内几乎所有的物体交互都要依靠碰撞检测来触发。在游戏制作中,给需要碰撞检测功能的物体添加碰撞检测器组件boxcolliger便可实现碰撞检测。
当角色触碰到4 个具有特殊效果的道具时,激活特殊效果,销毁道具,开启效果持续时间计时器。
当角色触碰到金币时,销毁金币,增加玩家的积分。如果角色此时拥有磁铁道具,那么当代表磁铁效果返回的碰撞检测器触碰到金币时,先使金币平滑地飞向角色,制作磁铁吸引的效果,当金币触碰到角色时,金币销毁,增加玩家的积分。
当角色触碰到障碍物时,角色死亡,执行死亡动画。
障碍物碰撞。障碍物用来阻挡游戏角色的前进,并且在游戏角色碰撞到障碍物时结束游戏。对于大部分障碍物,都可以直接添加碰撞器使其在碰撞时触发死亡效果。有两种障碍物是特例,一种是车辆,游戏中的两种车辆在玩家碰撞到时会触发死亡效果,但是当游戏角色跳跃到车的顶部时,是可以在上面行走的,所以在添加碰撞器时要注意这一点;而另一种是下方有空间的挡板,游戏角色在没有二连跳时无法越过,只能通过从下方空间翻滚经过,在游戏制作中,翻滚动作虽然会播放翻滚动画,但是碰撞器并不会播放翻滚动画,所以要在播放翻滚动画时短暂地关闭碰撞器,防止碰撞到障碍物,在经过障碍物后再次将碰撞器开启。
2.2.8 路面随机生成障碍物
酷跑类游戏通常没有通关功能,所以只要玩家可以保持游戏不失败,就可以无限进行游戏。而前面讲到本游戏实现无限道路的方法为交替移动两块足够长的道路,玩家需要在道路上使用道具或躲避障碍物。为了增加游戏的趣味性,游戏制作中需要在道路上随机生成各种障碍物或道具。但是在制作过程中发现,如果道具的生成完全随机化,那么会出现大量的物品重叠或没有通路等问题。所以为了保证在相对随机的环境下也能正常游戏,解决办法为手动制作多组道路上的障碍物排列,每当角色移动到新的道路时,随机选取一组预先制作好的障碍物排列。
2.2.9 界面显示
除了游戏主要的环境和角色以外,还需要多个UI 界面来显示一些游戏内数值。本游戏设置了积分显示,道具持续时间显示。积分显示为记录玩家拾取金币的数值,普通情况下玩家每拾取1 个金币,积分+1,在双倍积分道具效果持续时间内,玩家每拾取一个金币,积分+2。道具持续时间显示为记录玩家当前已激活道具的效果剩余时间,当玩家触碰到道具时开始计时,当计时时间结束时道具效果结束。
金币积分计数代码:
public override void HitItem()
{ base.HitItem();
GameAttribute.instance.AddCoin(1); }
2.2.10 游戏进程控制
所有单机都必不可少地设置开始暂停等游戏进程控制。本游戏一共设置了开始游戏、暂停游戏、恢复游戏、重新开始游戏和退出游戏五个选项。第一次打开游戏时弹出开始游戏和退出游戏。点击开始游戏按钮,游戏开始并弹出暂停按钮;点击退出游戏按钮,游戏关闭;点击暂停按钮,游戏暂停并弹出恢复游戏按钮和退出按钮;点击恢复游戏按钮,游戏继续;点击退出游戏按钮,游戏关闭。当角色死亡时,弹出重新开始游戏按钮和退出游戏按钮。点击重新开始按钮,游戏重新开始,开始界面与第一次进入时一致;点击退出游戏按钮,游戏退出。通过封装方法到按键,由点击事件激活。
当游戏重新开始时,需要将一切数值清空,包括玩家已获得的积分,当前已激活道具的剩余时间等,还要重置角色的位置和道路的位置。
2.2.11 动画与声音播放
游戏过程中角色需要切换不同的动画,正常跑步时播放跑步动画,向左或向右移动时播放移动动画,跳跃时播放跳跃动画,翻滚时播放翻滚动画,碰撞障碍物时播放倒地动画。
本游戏一共有五种不同的音效,分别为菜单键点击音效,金币拾取音效,触发道具音效,碰撞障碍物音效和滑动操作音效。
3 游戏测试
在游戏制作完成后,需要进行游戏测试,用来测试游戏中是否有与预期不符的异常。因为Unity3D 引擎可以实时测试的优点,我们可以在游戏发布前先进行初步的流程测试。
首先测试游戏主角是否能根据玩家的操作进行正确的动作,然后是游戏中的4个道具是否可以正确地激发效果。同时,道具在激活时,游戏界面右上角的道具效果计时界面也要正确地为道具效果计时,在倒计时结束时道具效果也要同时消失。然后是游戏主角在拾取金币时是否能正确地记录金币数,在双倍积分效果的持续时间内拾取金币是否可以正确地增加双倍金币数。还有游戏场景内的各个障碍物测试,不同的障碍物拥有不用的碰撞区域,游戏角色在碰撞到障碍物时能否顺利触发死亡效果。最后是游戏菜单,对所有的游戏菜单按键测试,例如开始、暂停、退出等按键能否正确地实现。
4 结语
游戏无论是在汽车的选择、关卡的选择还是在音效这一感官体验上,都能给玩家带来不一样的视觉感受与听觉感受。主菜单界面的帮助界面能够帮助新手玩家更好地了解本游戏的玩法,选择不同的车辆进行游戏会给玩家带来焕然一新的感觉,不同的关卡具有不同的难易程度,能够适合不同的玩家群体,震撼的游戏背景音乐能够带来刺激的听觉享受。