基于Unity3d引擎的ACT游戏设计与实现.docx
《基于Unity3d引擎的ACT游戏设计与实现.docx》由会员分享,可在线阅读,更多相关《基于Unity3d引擎的ACT游戏设计与实现.docx(37页珍藏版)》请在冰豆网上搜索。
基于Unity3d引擎的ACT游戏设计与实现
基于Unity3d引擎的ACT游戏设计与实现
Designandimplementationofactgamebasedonunity3dengine
内容摘要
从游戏诞生之始到现在,游戏市场就发生了非常大的变化,从卡带的游戏机到现在的电脑,专门的游戏主机等。
在此之中,像素游戏是一个很重要的过渡期,像素图由于占空间少,颜色少,所以在最初阶段的电子计算机上时代中,就被采用来作为制作游戏的标准图片形式,因为最开始的游戏处理芯片比较低级,自然不能跟如今的3d游戏相比较了,能运行的图片都有严格的颜色和大小的限制。
而且图片几乎都是以动态的形式出现的。
在如今的游戏开发中,Unity的工具的发明,使能向往游戏开发的人入门游戏开发不再困难。
在本课题中,将使用Unity引擎开发像素风格的2d横板动作游戏,其中会复刻多个经典像素游戏中的游戏技能,结合当前火热的Unity物理引擎,对以前的游戏以当前的技术进行重现,对以后游戏开发的思路有很大的参考价值
关键词:
像素游戏2d横板动作游戏Unity物理引擎
Abstract
Fromthebeginningofthegametonow,thegamemarkethaschangedalot,fromthegamemachinewithcardtothecomputerandspecialgameconsole.Amongthem,thepixelgameisaveryimportanttransitionperiod.Becausethepixelimagetakesuplessspaceandcolor,itwasadoptedasthestandardimageformformakinggamesintheearlyeraofelectroniccomputer.Becausethefirstgameprocessingchipisrelativelylow-level,itcan'tbecomparedwithtoday's3Dgames,andthepicturesthatcanrunhavestrictappearanceColorandsizelimits.Andpicturesarealmostalwaysindynamicform.Intoday'sgamedevelopment,theinventionofunity'stoolmakesitnolongerdifficultforpeoplewhocanyearnforgamedevelopmenttostartgamedevelopment.Inthisproject,wewilluseunityenginetodevelop2Dboardactiongamewithpixelstyle,inwhichwewillcopythegameskillsofseveralclassicpixelgames,andcombinethecurrenthotunityphysicalenginetoreproducethepreviousgameswiththecurrenttechnology,whichhasgreatreferencevalueforthefuturegamedevelopmentideas
Keywords:
pixelgame2Dboardactiongameunityphysicalengine
1.研究课题及意义
动作游戏(ActionGame)是游戏中的一种。
它强调玩家的反应能力和手眼的配合。
以游戏机为主、电脑为辅。
动作游戏的剧情一般比较简单,主要是通过熟悉操作技巧就可以进行游戏。
这类游戏一般比较有刺激性,情节紧张,声光效果丰富,操作简单。
在动作游戏中,在FC游戏家用机的时代中,有一些比较著名的作品,如高桥名人的冒险岛,松鼠大战等的游戏横板游戏作品,以引人入胜的剧情和巧妙地关卡设计,成为了8090年代地难忘的游戏之一,在现在的PC游戏作品中,动作游戏的优秀作品更是数不胜数,如StudioMDHR开发的游戏Cuphead,在在正式发售后大约一个月,这部作品销量就已经突破了百万大关,并达到了与《星露谷物语》《Undertale》《饥荒》等相当的水平,如今这款游戏已经成功登陆多个平台,成为最炙手可热的游戏作品之一。
还有TeamCherry开发的空洞骑士,这是一款画面清新,难度挑战的动作冒险游戏,里面丰富的关卡设计和适中的难度,吸引了很多玩家为之疯狂。
虽然现在各种moba游戏和射击游戏类的网游很多,但是在动作游戏从诞生至此,虽然不算是非常炙手可热,但是经过了多年依旧魅力不减,主要的玩家群体是有很多玩家愿意通过自己的探索,自己去进行游戏的探险,而不是与他人合作,这类游戏对于玩家来说就是对游戏作品的敬仰,对游戏开发者来说就是智力与创造力的挑战
动作游戏的分类其实有很多,而本次研究课题是动作游戏中的横板闯关游戏,在游戏中,玩家通过控制主角用武器去攻击敌人,消灭敌人以过关的游戏,在游戏中,将运用到游戏AI常用到的有限状态机框架去开发,这种框架在其他的一些游戏中非常常见,运用这个框架能使敌人AI更具有智能性,使游戏更具趣味,研究这个课题的目的是在于能运用自己所学的知识,开发出一个完整的游戏。
为以后自己能力的提升提供一个踏脚石。
2.游戏的设计工具
游戏的设计工具有编程工具MicrosoftVisualStudio2017,图片绘制工具photoshop,游戏引擎工具Unity3d
编程工具VisualStudio2017:
MicrosoftVisualStudio是VS的全称。
VS是美国微软公司的开发工具包系列产品。
VS是一个基本完整的开发工具集,它包括了整个软件生命周期中所需要的大部分工具,如UML工具、代码管控工具、集成开发环境(IDE)等等。
在Unity与VisualStudio的关系中,在旧版本Visualstudio2015以前是难以支持Unity的开发的,知道Visualstudio2015中新增了VisualStudioToolsforUnity 插件,给Unity的程序开发工作提供了支持,时至现在,在Visualstudio2017版本已经是完全支持Unity3d的程序开发了,在Visualstudio2017版本中能够快速找到Unity3d的脚本组件,为Unity3d的程序开发提高了效率。
图片绘制工具photoshop:
AdobePhotoshop,简称“PS”,是由AdobeSystems开发和发行的图像处理软件。
Photoshop主要处理以像素所构成的数字图像。
使用其众多的编修与绘图工具,可以有效地进行图片编辑工作。
至今在各个领域中活跃着,如平面设计等,在2d游戏的开发中,必然少不了的是游戏素材,使用Photoshop能快速地绘制我们所需的2d游戏素材,在AdobePhotoshop中能导出多种格式的图片,在Unity3d中都能很好地支持。
游戏引擎工具Unity3d:
Unity3D是由UnityTechnologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。
使用Unity3d可以创建属于自己地2d和3d游戏,Unity3d内部有很多功能丰富的API,能很多地满足了游戏开发人员的各种开发需求。
而且Unity3d是完全基于.net环境的,c#语言对其有很好的支持。
3.游戏详细设计
本详细设计将对游戏中重要的,复杂的逻辑进行详细讲解,具体详细地讲解游戏中各种逻辑地实现,为后续希望开发同类游戏的开发者提供借鉴与参考。
3.1设置游戏场景地地图
由于2d游戏的地图是采用sprite精灵图片,由于手动摆放地图图片十分浪费时间,而且难以保证图片之间是否存在缝隙,地图由于是不规则形状,为地图设置碰撞器也是十分困难,而且十分耗费时间的事情。
使用Unity系统自带的tilemap地图构建系统,这个新功能是Unity2017.2以及以上版本提供了这样的新功能,这个新功能代替了传统的2d游戏地图的制作方式,大大提高了开发人员制作游戏地图的速度。
首先,介绍一下Tilemap的基本概念,Tilemap用起来其实就和现实中画画一样,它由以下五个基本部分组成:
Sprite(精灵):
纹理的容器。
大型纹理图集可以转换为精灵图集(SpriteSheet)。
Tile(瓦片):
包含一个精灵,以及二个属性,颜色和碰撞体类型。
使用瓦片就像在画布上画画一样,画画时可以设置一些颜色和属性。
Palette(调色板):
当你在画布(Canvas)上画画时,会需要一个位置来保存绘画的结果。
类似地,调色板(Palette)的功能就是保存瓦片,将它们绘制到网格上。
Brush(笔刷):
用于将画好的东西绘制到画布上。
使用Tilemap时,可以在多个笔刷中任意选择,绘制出线条、方块等各种形状。
Tilemap(瓦片地图):
类似Photoshop中的图层,我们可以在Tilemap上画上Tile。
只有有了Tilemap的工具,开发人员就可以根据美术素材,快速进行2d场景地图的绘制了
3.2Tilemap部分其它工具
Grid(网格):
用于控制网格属性的组件。
Tilemap是Grid的子对象。
Grid类似于UICanvas(UI画布)。
Tilemap渲染器(TilemapRenderer):
用于控制Tile在Tilemap上的渲染,控制诸如排序、材质和遮罩等。
3.3利用Tilemap开始进行地图制作
有了上面的理论之后,就开始进行实际的地图制作了
实现点击window菜单按钮,打开2d->tilepalette,打开调色板,创建一个新的调色板,命名为TileSet1,把素材用的精灵图片拖到调色板上
此时在层次面板上,点击右键2dObjectàtileMap,创建出一个Gird节点的物体
在Gird节点下创建游戏需要的地板,背景和其他的一些装饰等的一些Tilemap节点,分别命名为Platforms,Background,Decoration,ForegroundDecoration
点击Platforms,同时在调色板面板上的ActiveTilemap这里选择Platforms,点击笔刷工具,开始绘制地板
点击Gird节点的Background节点,同时在调色板面板上的ActiveTilemap这里选择Background,这里虽然之前绘制了Platform的Tilemap,但是只要在ActiveTilemap选择了另外的层之后,就不会影响之前的Platform。
由于绘制了多层的Tilemap之后,而且tilemap和图片一样,都有绘制的顺序的,要考虑到Tilemap之间的渲染顺序,所以,在每个Tilemap的Tilemaprenderner组件的AdditionalSettings的sortinglayer中,为每个Tilemap添加对应的sortinglayer。
因为主角必须在地上行走,所以为地板和墙壁的Tilemap添加碰撞体,虽然tilemap本质上是精灵图片,可以加盒子碰撞器,但是按照传统的盒子碰撞器的添加方法,效率不高,所以,采用的是Tilemap独有的碰撞器添加方法添加Tilemapcollider2d,但是这种方法为每个tilemap的格子都添加盒子碰撞器,会消耗大量资源,因此,再为这个tilemap添加一个CompositeCollider2d,这种碰撞器会根据Tilemap的形状计算,压缩一些不必要的Tilemap碰撞器,只要在Tilemapcollider2d组件上,UsedByComposite勾选,CompositeCollider2D才会生效但是,在设置完后,运行游戏发现游戏的地板和墙壁掉下来,于是将地板和墙壁的Tilemap的2d刚体设置为Static,因为地板和墙壁是不会动的
3.4制作动画
将玩家各个动作的序列图拖到层次面板上,将产生的动画文件保存到Animatons的文件夹下,
将野猪和稻草人的各个动作各个动作的序列图拖到层次面板上,将产生的动画文件保存到Animatons的文件夹下,
3.5制作玩家的控制方式(安卓控制脚本开发)
本游戏是支持pc平台以及安卓平台的,pc平台主要是通过键盘按键输入实现对玩家的控制,而安卓平台是通过屏幕的触摸检测,通过按下手机屏幕设置的UI按钮实现对玩家的控制,本小节介绍如何设置手机上的UI,实现对玩家的输入。
本小节的核心思路是通过触摸插件EasyTouch,对玩家的输入进行操作
由于已经导入了Easytouch插件,所以在层级面板上,就像普通的UGUI创建组件一样,右键创建EasytouchControlsButton,创建出左右键,和攻击跳跃等按键。
又因为需要脚本挂载的游戏物体,所以在层级面板上,创建一个空物体scripts,在这个脚本上,挂载一个Mobilescrpts在这个脚本中,编写玩家移动的方法,编写玩家攻击跳跃等的方法
在玩家控制脚本上,使用下面的两套预处理模板,分别处理当游戏在安卓平台上运行移动攻击逻辑和当游戏在标准windows平台上运行时的玩家移动攻击逻辑,这样就能实现无论是在windows平台或者是安卓平台,游戏都能运行。
#ifUNITY_ANDROID
安卓代码运行处
#endif
和
#ifUNITY_STANDALONE_WIN
windows标准平台运行处
#endif
3.6创建角色的摄像机
由于游戏是采用2d的游戏模式,玩家移动时候需要有一个摄像机进行玩家移动跟随。
在Unity的Packagemanage中,内置了一个Cinemachine的插件,CineMachine能创建各种类型的摄像机,非常适合在本项目中使用。
同时,CineMachine还提供了多种功能让我们方便实现游戏中的其他功能。
由于本项目是2d游戏,在菜单栏中,点击Cinemachine的菜单项创建一个2dCamera
3.6.1角色跟随功能的实现
在Cinemachine中,由于这个组件已经为我们内置了非常多的常见的相机功能,也包括角色跟随的功能,用这个插件,实现这个功能的步骤非常简单,只需将整个角色的游戏物体的transform拖进新创建的2dCamera中
3.7开发玩家主角的各种状态
3.7.1地面状态
由于是2d游戏,玩家需要在地面上行走,还有当玩家需要进行跳跃时,要检测是否能进行跳跃,所以检测玩家是否在地上,是必不可少的条件。
以往在3d游戏中,都只是直接在玩家身上只是添加一个全身的碰撞盒子,用全身的碰撞盒子和地面进行碰撞检测,但是,在本项目中,存在墙壁,以及其他状态都站在地上,很难和其他状态进行区分,在以后的工作中,还需要进行墙壁的碰撞检测,因此只是用玩家一个碰撞盒进行检测和以后的墙壁碰撞检测相互矛盾,因此,在玩家的物体上挂载一个空物体,用这个空物体进行碰撞检测,但是,如果给这个空物体添加碰撞盒,必然会和玩家身上的碰撞盒发生碰撞,对检测造成不必要的错误,因此,使用其他的方法进行碰撞检测,在这里,使用物理函数Physics2D.OverlapCircle()进行射线检测
物理函数Physics2D.OverlapCircle()函数是检测某个碰撞体是不是在某个圆形区域内,返回碰撞体。
在玩家的物体下,挂一个空物体,命名为GroundCheck,用于检测玩家是否已经着地,如下图所示
检测玩家是否着地是用Physics2D.OverlapCircle()函数来检测是否着地,其中有三个参数,第一个参数点,第二个参数是检测的半径,第三个参数是检测的层
定义三个参数,其中第一个是transform类型公有变量groundCheck,groundCheck.position这个参数传进检测函数里面,用于指定检测的物体的点,第二个参数是半径groundCheckRadius,第三个是定义一个公有的Layermask变量whatIsGround,等脚本编译后,在Unity编辑器里将Platforms的tilemap添加一个Layer为ground,把Platforms拖进脚本的ground中
核心实现代码如下:
publicTransformgroundCheck;//检测玩家是否着地
publicLayerMaskwhatIsGround;//地面层
isGrounded=Physics2D.OverlapCircle(groundCheck.position,groundCheckRadius,whatIsGround);
3.7.2设置多段跳(二段跳)
由于玩家在跳跃的过程中,y轴上的速度有明显的区别,在玩家上跳的过程中,玩家的速度方向沿着y轴的正方向增加,下落的过程中,玩家的速度方向沿着y轴的负方向减少。
因此,可以用玩家速度的方向,把一套完整的跳跃的部分区分开。
把一套跳跃动作分为三个部分,在Animator的参数列表中定义一个y轴上的速度,以y轴上的速度制作玩家跳跃的混合树,混合树分为三个阶段,第一个阶段是上升,第二个阶段是上升到顶点,第三个阶段是玩家达到最高点之后的下落阶段
3.7.3墙壁滑动状态
在游戏中,玩家触碰到墙壁并且按着前方向的话,玩家不会因为重力马上掉下地面,而是和墙壁类似一种摩擦力让玩家游戏对象缓慢从墙壁上滑下来。
由于玩家是在空中,并且触碰到墙按着前方向的时候,才能拥有这种行为,因此,玩家需要满足多项条件,第一项,玩家是在空中的状态,而不是在地上的状态,在地上触碰到墙,是无法拥有这种状态的。
第二项,玩家是触碰到墙,因为这种状态只有触碰到墙才能发生,第三项是,玩家按的方向和玩家游戏对象的前方向一致,所谓前方向,就是玩家的正面面向的方向,只有满足这三个状态,才能触发玩家沿着墙壁缓慢滑下的行为。
在玩家的物体下,挂一个空物体,命名为wallCheck,用于检测玩家是否已经触碰墙壁
检测玩家是否着地是用射线检测的方式检测玩家是否触碰墙壁,在本项目中不使用碰撞盒子检测的方法,而是使用射线检测,其对应的函数是Physics2D.Raycast(),用射线检测的好处是不用主角身上挂载太多碰撞盒子,其中有四个参数,分别是检测物体的点,方向,射线距离,射线检测的层。
定义四个参数,其中第一个是transform类型公有变量wallCheck,wallCheck.position这个参数传进检测函数里面,用于指定检测的物体的点,第二个参数是方向,传进transform.right,即玩家的前方向,第三个参数是射线距离,定义一个float类型变量wallCheckDistance传进函数中,第四个参数是射线检测的层,把whatIsGround作为参数传进函数中
因为玩家身上具有多种状态,状态与状态如果不用一些标志位进行区分,就会造成程序的混乱,为此,为玩家的滑动状态创建一个标志位变量isWallSliding
在游戏的进行过程中,必须每个时候都要检测玩家当前所处的状态,因此,创建一个函数CheckIfWallSliding,用来检测玩家是否处于墙壁滑动的状态。
实现检测的核心代码如下
privatevoidCheckIfWallSliding()
{
if(isTouchingWall&&movementInputDirection==facingDirection&&rb.velocity.y<0&&!
canClimbLedge)
{
isWallSliding=true;//如果已经触碰到了墙壁,y轴上的速度是小于0(下落中),按键输入的方向是玩家正面的朝向
}
else
{
isWallSliding=false;
}
}
有了能检测玩家是否处于滑动状态的函数,就必然要有处理玩家滑动行为的方法,在检测玩家滑动状态结果中,根据检测的结果,处理玩家墙壁滑动的行为,实现滑动行为的代码如下
if(isWallSliding)//当玩家正在处于墙壁滑动的状态时
{
if(rb.velocity.y<-wallSlideSpeed)
{
rb.velocity=newVector2(rb.velocity.x,-wallSlideSpeed);
}
}
3.7.4玩家向前跳
由于自己定义的方法只能是在原地进行跳跃,在游戏中,常常需要根据玩家输入的方向进行相应方向的跳跃,所以,在原来的基础上,结合输入的方向,往该方向添加相应的力便能往该方向进行跳跃。
实现步骤:
因为开始的跳跃是只是在原地进行跳跃,由于游戏有多个跨度比较大的平台,玩家需要跳跃到对应的平台完成任务,所以定义一个在空中移动的力量movementForceInAir
定义一个Vector3的变量,把movementForceInAir*movementInputDirection的值传进这个变量。
作为x的值。
刚体通过AddForce(),添加这个力添加到玩家刚体上
3.7.5二段跳跃和蹬墙跳跃
在一些游戏中,二段跳和蹬墙跳跃是拓展玩家操作的一个有实际意义的操作。
二段跳的使用场景玩家在跳上一些跨度比较大,或者高度比较高的平台的时候,二段跳可以帮助玩家弥补跳跃宽度或者跳跃高度不足的缺陷。
蹬墙跳的使用场景是玩家在一些需要跳跃一些比较高的高台时,而且玩家使用二段跳也无法达到的高度时,玩家可以借助墙壁,将自己身体反弹,通过不断反弹,达到玩家能够达到的高度。
二段跳:
当玩家在空中按下一次跳跃时,再按下跳跃键的时候,让玩家往一个方向上产生一定大小的力
蹬墙跳:
玩家触碰到墙,通过判断玩家是否能达到能蹬墙跳的条件,然后根据玩家的朝向,往一定方向产生一定大小的力
检测蹬墙跳的核心代码
if(!
isGrounded&&isTouchingWall&&movementInputDirection!
=0&&movementInputDirection!
=facingDirection)
{
WallJump();//如果不在地上,触碰到墙,有输入方向
}
实现蹬墙跳核心代码:
///
///墙壁跳跃
///
privatevoidWallJump()
{
if(canWallJump)
{
rb.velocity=newVector2(rb.velocity.x,0.0f);//用一个力来跳跃,而不是像正常跳跃那样直接设定速度,如果我们有一个向下的速度,我们失去了力,向下的速度越大,在你加上力后,我们向上的速度就越小
isWallSliding=false;//一开始就将y轴的速度设置为0
amountOfJumpsLeft=amountOfJumps;
amountOfJumpsLeft--;
Vector2forceToAdd