首页 基于Unity3d的第一人称射击游戏的实现(2)

基于Unity3d的第一人称射击游戏的实现(2)

举报
开通vip

基于Unity3d的第一人称射击游戏的实现(2)摘 要计算机游戏作为一种新兴的娱乐方式,已经融入到了人们的生活之中。近年来,游戏产业己经成为经济市场中增长速度最快的热点,是众所关注的焦点。Unity3D作为一款能跨平台的,界面友好,操作简单的工具,是一个全面整合的专业游戏引擎。本文研究了第一人称射击游戏,即通常所说的FPS游戏。本文基于Unity3D引擎,使用MicrosoftVisualStudio编写脚本,使用3dmax和Photoshop进行图形和建模处理工作。通过操作模拟角色达成各种动作,完成游戏。程序中有主菜单、暂停菜单和游戏结束菜单,能够选择重新开始...

基于Unity3d的第一人称射击游戏的实现(2)
摘 要计算机游戏作为一种新兴的娱乐方式,已经融入到了人们的生活之中。近年来,游戏产业己经成为经济市场中增长速度最快的热点,是众所关注的焦点。Unity3D作为一款能跨平台的,界面友好,操作简单的工具,是一个全面整合的专业游戏引擎。本文研究了第一人称射击游戏,即通常所说的FPS游戏。本文基于Unity3D引擎,使用MicrosoftVisualStudio编写脚本,使用3dmax和Photoshop进行图形和建模处理工作。通过操作模拟角色达成各种动作,完成游戏。程序中有主菜单、暂停菜单和游戏结束菜单,能够选择重新开始游戏和退出游戏等操作。在环境上展示了天空到陆地,森林草地到海面。角色能够完成跳跃,行走,切换武器等基本动作,射击敌人会增加积分,拾取的物体和角色状态能显示在GUI界面上。游戏中的敌人会自动生成并追踪玩家,在一定距离内会攻击玩家,被击败后会掉落弹药。若玩家被敌人击败,则结束游戏并切换到游戏结束菜单。关键词:Unity3d;VisualStudio;3dmax;Photoshop;FPS游戏ABSTRACTAsanewformofentertainment,computergameshavebeenintegratedintoourlives.Inrecentyears,thegameindustryhasbecomethefastestgrowinghotspotintheeconomicmarket,isthefocusofattention.Unity3dasacross-platform,user-friendly,easytooperatetool,isacomprehensiveintegratedprofessionalgameengine.Thisarticlestudiesthefirst-personshootergame,whichiscommonlysaidFPSgame.ThisarticleisbasedontheUnity3dengine,usingMicrosoftVisualStudioscripting,usingthe3dmaxandPhotoshoptheworkswithgraphicsandmodeling.Throughtheoperationofthesimulationroletoachieveavarietyofactionstocompletethegame.Theprogramhasmainmenu,pausemenuandGameEndmenu,canchoosetorestartthegameandquitthegameandsoon.Theenvironmentshowstheskytotheland,theforestmeadowstothesea.Thecharacterscanjump,walk,switchweaponsandotherbasicmovements,shootingenemieswilladdpoints,pickupobjectsandrolestatuscanbedisplayedintheGUIinterface.Theenemyinthegamewillautomaticallygenerateandtracktheplayer,atacertaindistancewillattacktheplayer,defeatedwilldropammunition.Iftheplayerisdefeatedbytheenemy,endthegameandswitchtothegameendmenu.Keywords:Unity3d;VisualStudio;3dmax;Photoshop;FPSgames1绪论  1.1选 快递公司问题件快递公司问题件货款处理关于圆的周长面积重点题型关于解方程组的题及答案关于南海问题 背景和意义1.1.1选题的背景2017年,中国的游戏行业整体营业收入大约为2189.6亿元,同比增长了23.1%。因此,游戏产业己经成为经济市场中增长速度最快的热点,是众所关注的焦点。游戏是文化创意产业里的一部分,创意经济是知识经济的核心内容,更是其经济的重要表现形式,没有创意就没有新经济。游戏设计是文化艺术创意和商品生产的结合,游戏产业的发展在中国的经济发展中具有十分重要的意义[1]。第一人称视角射击游戏(First-personShooter,FPS),顾名思义就是以玩家的主观视角来进行射击游戏。玩家们不再像别的游戏一样操纵屏幕中的虚拟人物来进行游戏,而是身临其境的体验游戏带来的视觉冲击,这就大大增强了游戏的主动性和真实感。早期第一人称类游戏所带给玩家的一般都是的屏幕光线的刺激,简单快捷的游戏节奏。随着游戏硬件的逐步完善,以及各种游戏的不断结合。第一人称射击类游戏提供了更加丰富的剧情以及精美的画面和生动的音效。Unity3D是一个用于创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的综合型的创作工具。Unity3D引擎来开发游戏有着以下优势:1.一次开发,多平台发布:Unity最多可以支持超过十个主流平台发布,程度节省开发成本和时间,却又可以在多个平台获取收益。2.容易上手,所见即所得:轻松开发,友好的可视化编辑界面功能强大,编写方便,极易上手。3.功能齐全,缩短开发时间:Unity引擎简单易用,几乎集成了游戏开发的所有功能,更有AssetStore提供开发所需的所有资源。1.1.2研究意义  随着手机等移动设备向着微型PC方向发展,用户对手机应用的要求也越来越高,追求高画质,高可玩性及高流畅性。向3D游戏发展是手机游戏发展的必然趋势。选择用Unity3D来完成本毕业设计,不仅是顺应了当前游戏开发的发展趋势,更是对个人技术及能力的一种锻炼。1.2第一人称射击游戏的国内外发展现状90年代初国外的3D游戏开始起步,第一部3D第一人称射击游戏是美国的卡马克的《重返德军总部》,最早3D游戏引擎由其开发的Doom引擎。在国内3D游戏始于2003年。目前,国内有了很多的研究在3D游戏上,但是,由于国内3D技术起步较晚,技术方面想比外国还是有不小差距,从设计理念到开发制作,国内能有自主研发的3D游戏引擎的,只有屈指可数的互联网公司,大部分游戏公司和游戏开发者还在用国外大型游戏公司所开发的游戏引擎,如Unity3D、虚幻、寒霜等。虽然最近国内出现许多优秀的游戏团队和游戏公司,开发了数款质量较高的游戏,例如《艾希》,《神舞幻想》等,但是比起《孤岛惊魂》,《巫师3》,《使命召唤》系列等国际游戏大作仍有不可逾越的差距,这也使得国内玩家的财富大量流向国外[2]。随着移动设备的硬件日益强大,如手机的硬件相比于以前电脑的配置还要强大,这样使用者在使用的时候,就会有大量应用的需求。目前有两种主流的手机操作系统:Android和IOS,这两种操作系统之所以成为主流,是因为庞大的系统应用在背后支持,所以,应用的开发在手机系统的竞争中尤为重要。然而,应用的跨平台移植会带来大量的问题,例如:开发语言不同,移植代价太高等,但是,国外开发的一款游戏引擎完美地解决了跨平台开发难的问题,那就是Unity3D引擎,虚拟机技术被运用到Unity3D中,独立于平台执行的游戏编译结果。对于3D引擎的研究,在国内还处于起步阶段,所以认真研究国外的优秀游戏引擎,对将来自主开发3D游戏引擎有巨大的帮助。1.3本文研究内容  本文主要研究并实现基于Unity3d的第一人称射击游戏的实现。使用该游戏软件,玩家可以以第一人称视角来操作角色,达成移动跳跃、切换武器、开火射击、拾取物品等操作。玩家在游戏中可以拾取各个地点的弹药补充子弹,且击败敌人后会掉落弹药、并获得积分。完成此游戏的设计,可以加深对Unity引擎开发游戏的理解,了解游戏制作的流程,在游戏的过程中体验带来不同的体验。1.4本章小结本章介绍了此次选课的背景以及意义,并分析了国内外游戏的发展状况,之后就本研究项目的实现的功能和内容做了初步的描述。2开发环境及主要开发工具简介  2.1Unity3DUnity3D是一个用于创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的综合型的创作工具,由UnityTechnologies开发。2005年6月Unity第一个版本1.0.1发布,标志着Unity的诞生。Unity是一个跨平台的游戏引擎,它利用了交互的图形化开发环境作为编辑器提供给开发者,可以运行在Windows和MacOSX操作系统下,并可发布应用到Windows、MacOSX、Android、iOS、Web、等平台[3]。Unity拥有以下主要特性:1.层级式的综合开发环境、视觉化编辑,详细的属性编辑器和动态游戏预览。2.跨平台支持。可以开发Windows、MacOSX、iOS、Android、Blakberry、Xbox、WindowsPhone等平台的应用程序。3.自动资源导入。项目中的资源会被自动导入,并根据资源的改动自动更新。4.基于Direc3D(Windows)、OpenGL(Mac、Windows)的图形引擎,并且有自己的API(Wii)。5.支持Bumpmapping、Reflectionmapping、Parallaxmapping、ScreenSpaceAmbientOcclusion,动态阴影使用的是ShaderMap技术,并支持Render-to-Texture和全屏PostProcessing效果。6.Shader编写使用ShaderLab语言,同时支持自有工作流中的编程方式或CG、GLSL语言。7.内置对Nvdia的PhysXphysicsengine支持。8.游戏脚本是基于Mono的Mono脚本,开发者可以使用JavaScript、C#或Boo语言编写脚本。9.音效系统基于OpenAL程序库,可以播放OggVorbis压缩音效,视频采用Theora编码。2.1.1事件函数Unity中的脚本不像常规程序在一个循环中的执行直到任务完成,而是通过调用一些事先声明好的函数,断断续续的将控制权传给一个脚本。当一个函数执行完毕后,控制权便又交回给Unity。这些函数就是事件函数。下面按照脚本的执行顺序介绍一些常用的Unity事件函数。Awake()。当前控制脚本实例被装载的时候调用。一般用于初始化整个实例时使用。Start()。当前控制脚本第一次执行Update之前调用。Update()。最常用的事件函数,每帧都执行一次。FixedUpdate()。每固定帧绘制时执行一次,与Update不同的是FixedUpdate是渲染帧执行,当渲染效率地下时,FixedUpdate的调用次数也会跟着下降。OnEnable()。当脚本被启用时调用。OnDisable()。当脚本被禁用时调用。OnDestroy()。当脚本的宿主物体被销毁的时候调用。Unity中编写的脚本一般都会绑定到一个GameObject上,这个GameObject就是程序中的一个基础元素。一个脚本的生命周期就是和它绑定的GameObjec息息相关的,当程序开始运行的时候,Unity会为每一个场景中活跃的GameObject上的脚本生成一个对象,而当脚本的宿主物体(即脚本所绑定的物体)被销毁的时候,脚本的对象也就不存在了[4]。Unity的脚本默认都会继承与MonoBehavior基类。不继承于MonoBehavior的类通常用来存放一些全局的数据,它在整个程序运行的过程中都是存在的。2.1.2  常用APITransform类。继承于Component类,用于描述和控制一个三维或者二维物体的位置、旋转和缩放属性,。在Unity的场景中,每一个物体都有一个Transform组件,被用来存储和操控位移、旋转和缩放。Transform允许拥有父对象,子对象的属性基于父对象发生偏移[5]。Transform的常用属性有:(1)childCount:当前Transform所拥有的子对象的数量。(2)eulerAngles:旋转的欧拉角度数。(3)localEulerAngles:当前Transrom相对于父对象的旋转欧拉角。(4)localPostion:相对于父对象的位置(5)localRotation:相对于父对象的旋转。(6)Parent:此Transform的父对象。Transfrom的常用方法:(1)DetachChildren:分离所有子对象。(2)Rotate:指定一定的旋转角度给当前的对象。(3)RotateAround:让当前的对象绕着某一个指定的点旋转一定的角度。(4)Translate:让当前对象的位置沿着指定的方向和距离移动。Vector3是三维向量类,使用它来记录一个物体在三维空间里X、Y、Z轴上的位置、旋转和缩放信息。Vector3类定义了一些静态变量来代表一些常用的三维向量,如Vector3.back表示的的是Vector3(0,0,-1),Vector3.forward表示的是Vector3(0,0,1)等等。在编程过程中可以直接快捷的使用这些变量。Vector3的常用属性有:(1)Magnitude:返回当前三维向量的长度(只读)。(2)Normalized:返回当前向量的 标准 excel标准偏差excel标准偏差函数exl标准差函数国标检验抽样标准表免费下载红头文件格式标准下载 向量。(3)X:当前向量的X值。(4)Y:当前向量的Y值。(5)Z:当前向量的Z值。Vector3的常用方法有:(1)Angle:返回两个Vector3向量之间的夹角。(2)Cross:返回两个Vector3向量的叉乘。(3)Lerp:在两个Vector3向量之间线性差值。(4)MoveTowards:直线移动一个点到目标点。  2.1.3材质、灯光和着色器材质,简单的说就是物体看起来是什么质地。材质可以看成是材料和质感的结合,在渲染过程中,它代表的是物体表面各种可视属性的结合,比如表面的色彩、纹理、光滑度、透明度、反射率、折射率、发光度等[6]。着色器的作用就是把物体表面的各种属性结合起来。Unity内置了有80多个着色器,能够满足大多数基本场景的渲染。这些着色器分为标准着色器、透明着色器、透明镂空着色器、自发光着色器、反射着色器五大部分。开发者可以使用ShaderLab语言开发更多自定义的着色器,来满足实际项目的需要。没有灯光,什么都是不可见的。因此,给场景物体赋予了材质以后,还需要配合灯光将它展示出来。Unity内置有四种类型的灯光,它们分别是平行灯光(DirectionalLight)、点灯光(PointLight)、聚光灯(SpotLight)、区域灯光(AreaLight)。平行灯光多用来模拟太阳光,点灯光和聚光灯多用来模拟室内照明装置,区域灯光可以用来制作区域发光体。在Unity的工程里创建好一种类型灯光后,可以在监视器(Inspector)窗口里调节它的具体属性,如图2-1所示。图2-1灯光的属性调节Type可以切换灯光的类型,Range改变灯光的照射范围,Color代表灯光的颜色,Intensity是灯光的强度,ShadowType是指灯光的阴影类型[7]。2.23DMAX3DStudioMax,常简称为3dsMax或3DMAX,是Autodesk公司开发的基于PC系统的三维动画渲染和制作软件,其前身是基于DOS操作系统的3DStudio系列软件。3DStudioMaxWindowsNT组合的出现一下子降低了CG制作的门槛,首选开始运用在电脑游戏中的动画制作,后更进一步开始参与影视片的特效制作。3DMAX具有以下优势:性价比高:3DSMAX所提供的强大的功能远远超过了它自身低廉的价格,一般的制作公司就可以承受的起,使作品的制作成本大大降低,而且对硬件系统的要求相对来说也较低,一般普通的配置就可以满足学习的需要。使用者多,便于交流:在国内外拥有众多的使用者,便于交流。上手容易:3DMAX的制作流程十分简洁高效,可以很快上手,后续的高版本中操作性也十分的简便,操作的优化更有利于初学者学习[8]。2.3VisualStudioVisualStudio是一套完整的开发工具,用于生成ASP.NETWeb应用程序、XMLWebservices、桌面应用程序和移动应用程序。VisualBasic、VisualC#和VisualC都使用相同的集成开发环境(IDE),这样就能够进行工具共享,并能够轻松地创建混合语言解决 方案 气瓶 现场处置方案 .pdf气瓶 现场处置方案 .doc见习基地管理方案.doc关于群访事件的化解方案建筑工地扬尘治理专项方案下载 。另外,这些语言使用.NETFramework的功能,它提供了可简化ASPWeb应用程序和XMLWebservices开发的关键技术。本文研究时使用了VisualStudio2017,目前VS已经更新了Unity的编译组件,是广大开发者的首选。VisualStudio2017在开发上相对于之前版本有着以下特点:1.为任何开发、应用和平台提供无与伦比的效率。2.使用VisualStudio2017开发适用于Android、iOS、Windows、Linux、Web和云的应用。3.快速编码、轻松调试和诊断、时常测试,并且可以放心地进行发布。还可通过构建自己的扩展,以便扩展和自定义VisualStudio[9]。2.4Photoshop  AdobePhotoshop,简称“PS”,是由AdobeSystems开发和发行的图像处理软件[10]。Photoshop主要处理以像素所构成的数字图像。使用其众多的编修与绘图工具,可以有效地进行图片编辑工作。Photoshop有很多功能,在图像、图形、文字、视频、出版等各方面都有涉及。以下是Photoshop中基本的理论知识介绍:1.位图:又称光栅图,一般用于照片品质的图像处理,是由许多像小方块一样的"像素"组成的图形。由其位置与颜色值表示,能表现出颜色阴影的变化。在Photoshop主要用于处理位图。2.矢量图:通常无法提供生成照片的图像物性,一般用于工程技术绘图。如灯光的质量效果很难在一幅矢量图表现出来。3.分辨率:每单位长度上的像素叫做图像的分辨率,简单讲即是电脑的图像给读者自己观看的清晰与模糊,分辨率有很多种。如屏幕分辨率,扫描仪的分辨率,打印分辨率。4.图像尺寸与图像大小及分辨率的关系:如图像尺寸大,分辨率大,文件较大,所占内存大,电脑处理速度会慢,相反,任意一个因素减少,处理速度都会加快。还有很多Photoshop的具体工具的使用,比如通道、图像的色彩模式、滤镜以及绘制图像、处理照片过程中所需要用的快捷键等等。2.5本章小结  本章介绍了此次所用到的开发工具。其中,Unity3D负责整个游戏框架的构建;Photoshop负责UI的制作;编写脚本方面使用VisualStudio、使用JavaScript和C#编写;3dmax负责弹药箱模型的建模。3  游戏策划3.1  游戏简介游戏的环境在一个海岛上,主角要与源源不断复生的机械战士对抗,击败敌人时会掉落弹药。击败的敌人越多,积分越多。游戏操作如下:使用WASD移动,移动时按Shift奔跑,空格键跳跃,鼠标控制视角,鼠标左键开火,右键瞄准,R装弹,数字键123切换武器。游戏总共由三个场景构成:主菜单场景、游戏场景、游戏结束菜单场景。通过在这三个场景之间切换,达成游戏的效果。本课题整个游戏的场景系统设计图如下图3-1所示:图3-1游戏场景系统设计示意图3.2  游戏元素设计游戏元素,即角色、道具、实体对象具有与玩家进行交互的属性,并且可以根据玩家的操作改变部分属性,这种在游戏场景内可以与玩家进行某种方式交互的虚拟物体被称之为游戏元素[11]。在本次课题中最主要的游戏元素就是主角使用的武器:手枪和步枪以及小刀,其中手枪和步枪的图标如图3-2和图3-3所示。这三种武器能够被玩家自由切换,且能够实现以下功能:1.在每次切换时,都播放一个拿起该武器的动画。2.枪械填装弹药时,玩家无法开火,填装结束后才可开火。3.若弹夹内子弹为满,则无法填装,若弹夹为空,则无法发射子弹。4.按下鼠标右键,可以放大镜头,实现一个模拟瞄准的效果。图3-2玩家手枪装备图3-3玩家步枪装备3.3  游戏角色设计第一人称射击游戏顾名思义,玩家以第一视角来进行游玩,摄像机所看到的视角和人眼所看到的视角相同。主角模型需要双手和武器,效果图如下图3-4所示。图3-4主角视角玩家在三种武器中任意切换,且武器能够统一接收指令,在使用一种武器时,其他武器是隐藏的。三种武器的模型动画都划分为第一人称控制器的子类,游戏角色功能模块图如下图3-5所示。图3-5玩家角色模块设计3.4  游戏敌人设计游戏敌人设置为机械战士,使用步枪进行攻击主角,其中敌人模型如图3-6所示。游戏中的敌人行为主要分为巡逻(patrol)、攻击(attack)等行为状态,各个不同行为下执行不同的动作,通过程序控制角色的动作。敌人模块与Player模块相似,通过父类的来控制子类的开火。游戏中的敌人会源源不断的生成,但是如果同时出现上百个那也是不可能的,在生成敌人时,最大同时存在敌人数为3个,主角每击败一个就获得100分,并掉落弹药,同时再生成一个敌人,以此挑战高分。图3-6敌人模型3.5  游戏环境设计本游戏的环境主要由地形、光照、水和其他的物体如船、房屋模型等组成。大致过程如下:创建Empty命名为Environment,在其下创建地形。地形尺寸大小的调整可以通过修改菜单中的Resolution中的参数来实现,不过只有在地形被创建之后,该菜单才可用,并且它的数值的修改可以实时修改当前地形的尺寸大小。点击Terrain->Setting->Resolution,如下图3-7示。从上至下依次为地形的宽度、高度、长度、高度的像素大小设置,地形尺寸的大小还可以设置种植植物密度等[12]。图3-7修改地图尺寸在Unity3d中地形创建过程主要是使用terrain工具进行地形编辑的过程。地形编辑工具包括地形高度工具(Raise/LowerTerrain)、最大高度工具(PaintHeight)、平滑工具(SmoothHeight)、纹理工具(PaintTexture)、植树工具(PlaceTrees)、种草工具(PaintDetails)、地形设置(TerrainSettings)。通过灵活的使用这些编辑工具,可以快速的建立出一个复杂的游戏地形[13]。其中地形编辑器的种草工具如下图3-8所示。图3-8地形编辑器之PaintDetails首先需要的是将地形中间部位隆起,作为小岛。在场景面板中选择地面对象,会在inspector中显示与之对应的属性,包含有:Position、Rotation、Scale以及地形编辑工具,合理使用地形高度工具、平滑工具等编辑地形的起伏,达到需要的效果。之后使用纹理工具(PaintTexture)将导入的地形纹理资源加入到纹理工具的纹理列表。选择不同的纹理并配合大小不同的笔刷,在地形上点击,很快就可以完成纹理的贴图工作。在本地形中,共使用了5种不同纹理的贴图。如图3-9所示。图3-9地形纹理编辑器下一步就是在已经建立好的地形上添加植被。草和树木的设置方法和地形材质的设置方法类似,也是先点击按钮来添加所需要的花草和树木,然后再需要种植植物的区域刷出相应的植物即可。在此工具中植物的选择是有限的,通过加载游戏植物库来获取。之后再添加资源包里的房屋、船、岩石等模型。初步建立好地形后,在地形设置中修改风力,风力值越大,添加的植被所呈现的被风吹过的力度就越大。然后将资源包中的水的预制体导入到Environment中,就形成了一个四面环海的孤岛形象,如图3-10所示。图3-10小岛设计示意图光照的添加也十分重要,如果不设置光照系统,游戏将是一片黑暗。为了能够看出地形的起伏和环境效果,需要建立太阳光或者环境光。之前已经介绍过灯光的设置,这里就不再赘述。但是Unity5版本的实时动态光照对设备的配置要求较高,所以一般使用光照时会将整个地图的静态物体阴影做成贴图保存起来,之后游戏运行时直接调用现有的阴影贴图,这个过程被称之为烘焙(bake)。烘焙界面在Unity的工具栏Window->lighting->settings中进入,开发者可以设置让Unity后台自动烘焙。烘焙完成后,游戏在运行时是调用保存好的阴影贴图,所以运行起来占用系统资源少,更加流畅。但相对的Unity5烘焙需要的时间较长,较为复杂的地形有时需要数个小时或者更久。进过测试和学习,有以下几种方法可以缩短烘焙时长:1.修改lightmapsize的大小,越小速度越快。2.烘焙室外场景时,将lightmapper的值设置为progress;烘焙室内环境时修改为enlighten。3.修改scaleinlightmap的值为1。4.提高开发电脑的配置。为了让环境更加生动,给此环境添加一个背景音乐。Unity中可以通过给一个游戏对象添加AudioSource来添加音乐文件,支持MP3、ogg等常见的音乐类型文件,AudioSource可以控制音乐的播放以及单边音效等效果。音乐类型的文件在导入的时候,需要设置该音乐文件时一个2D音乐还是3D音乐。二者的区别在于,2D音乐无论“听者”的位置距离声源有多远,声音的大小都是不变的。3D音乐则类似现实世界中的音乐,当你离声源越近时听到的声音就越大。上面提到“听者”的概念,在一个环境里有了声音,没有人来听,那声音的存在是没有意义的,在Unity中也是一样。为了听到声音,需要在场景里添加一个AudioListener[14]。它通常作为组件添加在场景的主摄像机上,如下图3-11所示,给该地形添加一个海边音效的背景音乐,为了让音乐能够正常的循环播放,将PlayOnAwake与Loop勾选上。图3-11背景音乐的添加完成构建环境操作后,将整个环境移动到Project中的预制体文件夹中,起一个备份和随时调用的作用。3.6  本章小结本章介绍了游戏由三个场景组成,游戏的运行实际上是在这三个场景之间相互切换。并介绍了主要的游戏元素武器、主角和敌人的模型。之后描述了通过Unity游戏引擎的地形编辑工具能够快速地将游戏地形生成,分析了Unity5的烘焙功能的优劣,以及背景音乐的添加方法。4游戏功能模块4.1  GUI模块4.1.1  主界面菜单主界面菜单是打开游戏后进入的第一级菜单,所以需要注意的是,在创建好该场景后,在工具栏的File—BuildSettings内将该场景设置为第一级,其后数字显示为0。在做好准备工作后,开始主菜单的设计,创建Canvas后,在其下添加一个Empty命名为主菜单,并创建三个按钮依次对应开始游戏按钮、游戏帮助信息按钮、退出游戏按钮。其中游戏帮助信息按钮打开后可以实现:点击后显示操作游戏的方法(图文),再次点击时消失。所以还需要在Canvas内创建文本text和相应的图片image。使用Photoshop软件制作按钮等贴图如下图4-1所示.图4-1按钮贴图的制作创建脚本MainMenu,使它和一个创建的Empty关联,之后再将按钮和此项关联,调用其中挂载的脚本。脚本实现按钮的功能如下图4-2所示。publicvoidStartButton()//开始游戏按钮{SceneManager.LoadScene(1);}publicvoidQuitGame()//退出游戏按钮{Application.Quit();}publicvoidinformationButton()//游戏 说明 关于失联党员情况说明岗位说明总经理岗位说明书会计岗位说明书行政主管岗位说明书 按钮{if(text.enabled){text.enabled=false;image1.enabled=false;image2.enabled=false;image3.enabled=false;}else{text.enabled=true;image1.enabled=true;image2.enabled=true;image3.enabled=true;} }图4-2主菜单按钮功能的实现将关联了上述代码的脚本的Empty项命名为_GM(GameManager),EventSystem若没有和Canvas在同一层级上,游戏的按钮功能是无效的,如果EventSystem被误删,都需要重新创建一个。此时Mainmenu的设置到此结束,其组成应为下图4-3所示。图4-3MainMenu场景元素的组成4.1.2  游戏场景内GUI的显示暂停菜单、主角血条、准星、弹药的信息和受伤特效显示这五个模块,都位于第二个场景游戏场景内。暂停菜单与主菜单相似,在UI_Canvas内添加继续游戏按钮和重新开始游戏按钮,挂载脚本在Empty项Game_Manager上。其中暂停游戏的功能通过Time.timeScale来实现,当Time.timeScale=1.0f时,游戏时间为正常,当Time.timeScale=0f时,游戏时间停止。利用这个特性,在按下Escape按键后,使用该命令使时间停止,在继续游戏按钮函数内设置时间为正常。重新开始的效果通过UnityEngine中的场景管理器实现,让Unity重新加载游戏场景即可。具体实现暂停菜单各个按钮功能如下图4-4所示。privatevoidUpdate(){//按下esc后执行判断函数if(Input.GetKeyDown("escape")){PauseOrContinue();}}publicvoidPauseOrContinue(){if(UI.GetComponentInChildren().enabled){//发送消息令准星显示GameObject.Find("CrossHair").SendMessage("CrossHairON");UI.GetComponentInChildren().enabled=false;Time.timeScale=1.0f;}else{//发送消息令准星消失GameObject.Find("CrossHair").SendMessage("CrossHairOFF");UI.GetComponentInChildren().enabled=true;Time.timeScale=0f;}}publicvoidRestartButton()//重新开始按钮{SceneManager.LoadScene(1);}图4-4暂停菜单按钮功能的实现准星作为本射击游戏的射击参考点,有着以下功能:1.准星始终显示在屏幕中央。2.准星在打开暂停菜单时会消失,返回游戏场景后准星重新显示。则准星的x坐标值是屏幕的宽度减去准星贴图宽度的二分之一,同理y坐标则是高度。控制准星是否显示,是通过变量控制来实现:创建一个变量show为true,当打开暂停菜单时,对crosshair发送信息show为false,关闭则发送show为true,以此来控制准星的显示。实现利用变量控制准星的绘制如下图4-5所示。voidOnGUI(){if(show)GUI.DrawTexture(position,crosshairTexture);}图4-5绘制准星接下来是生命条的制作,玩家生命条由两层image组成,一层是空血条,一层是红色长条贴图,用来代表生命条。空生命条的制作如下图4-6所示。图4-6利用Photoshop工具制作空生命条将红色生命条的imagetype属性设置成为Filled,且FillMethod设置成为水平。如图4-7所示。图4-7红色生命条图片的设置这样通过脚本来控制FillAmount数值,就能控制此红色贴图的拉伸。Fillamount的最大值为1,而角色的生命值hitpoints初始值为100,令fillamount等于生命值的百分之一,就能达到受到伤害减少生命条的效果,其实现过程如图4-8所示。voidUpdate(){fillamount=hitPoints/100;bar.fillAmount=fillamount;}图4-8将生命值hitpoints转换为图片的fillamount弹药信息显示,其原理是通过在开火脚本的Update函数中,利用Update函数每帧执行一次的特性,向位于Canvas内的text发送信息,来实现实时显示弹药的剩余量,向文本发送信息的代码如图4-9所示。functionUpdate(){GameObject.Find("Canvas/Text").GetComponent(Text).text="     :"bulletsLeft"/"ClipsLeft;}//显示弹夹剩余子弹数量图4-9利用text显示弹药信息角色受伤特效,当玩家受到敌人攻击时,屏幕会短暂的变红,之后回复原状。达成该特效的方法是:创建两个image,其中一个image设置为完全透明,另一个设置为红色,利用脚本控制这两个image的显示。玩家未受到伤害时,令变量damage为false,当玩家受到伤害时,damage为true,让透明图片的颜色等同于红色图片,并在设定好的时间内复原成透明,达到期望的效果,其实现方法代码如图4-10所示。voidPlayDamagedEffect(){if(damaged){damage_Image.color=flash_Color;}else{damage_Image.color=Color.Lerp(damage_Image.color,Color.clear,flash_Speed*Time.deltaTime);}damaged=false;}图4-10受伤时屏幕闪红的功能实现游戏场景内的UI元素已全部介绍完毕。设计时在添加了角色受伤屏幕特效功能后,暂停菜单的按钮出现了无法响应的问题。之后通过另外创建一个UI_Canvas,以及重新编写暂停菜单的脚本得以解决,注意EventSystem需要和有按钮功能的Canvas在统一层级。完成后的游戏场景内GUI元素的展示如下图4-11所示。图4-11GameScene内的UI元素层级4.1.4游戏结束菜单游戏结束菜单是一个单独的场景,与主界面菜单类似。当主角的生命值为0时,会将场景转移到该场景。此场景除了包含一个作为背景的panel和显示游戏结束的image外,还包含三个功能按钮:重新开始、返回主菜单、退出游戏。这里可以直接调用之前的主菜单和暂停菜单中的按钮函数来利用,不需要另外写脚本。由于是直接调用之前介绍过的函数,所以这里就不再赘述。4.2  角色模块4.2.1  主角模块Unity作为一款专业的游戏引擎,已经包含了大量的资源包,将外部资源导入Unity有三种方式。第一种方式是存入工程文件夹。创建工程以后,在磁盘上会有一个工程文件夹,找到工程名下的Asset文件夹,将需要的模型资源、贴图资源复制粘贴到这里即可。为了工程结构的简洁明了以及方便查找资源,可以分别为模型和贴图创建自己的文件夹。第二种方式是在直接拖入到Unity中。在外部文件夹中选中需要导入的资源,直接拖拽进Unity的Project窗口中即可。第三种方式主要是用来导入.Unitypackage类型资源。Unitypackage是Unity打包文件生成的一种格式[14]。在Unity的顶部菜单栏找到Asset→ImportPackage→CustomPackage,在本地磁盘找到需要导入的Unitypackage文件点击确定就行了,其中Unity自带的资源包中就有第一人称控制器。使用方法就是在Project栏中import->Character资源包,之后将人物包中的FPScontroller预制体导入到场景中。当然,还需要根据自己的需求来更改或添加功能,如之后要添加的武器模块、Waypoint、Skybox等等。同时导入此第一人称控制器后,操作该控制器的输入控制器可以在Edit->ProjectSetting->Input中看到。根据需求,可以任意添加或删除功能按键。若要达到按下1、2、3切换武器和装弹的效果,需要将Size值加4,在最下方设置好对应的按键。当然也可以不用这种方法,转而直接监听玩家是否直接按下键盘按键,但是使用输入控制器能够让游戏更方便的进行跨平台移植,其他平台的操作方式不一定是鼠标键盘:如手机上的虚拟按键,主机上的手柄等。该界面展示如下图4-12所示。图4-12修改输入控制器示意图之后将FPScontroller更名为Player,在其下的FirstPersonCharacter中创建一个Empty的子类命名为Weapon。该项负责管理武器的切换和对武器发送信息。将资源包中的枪械和手模型导入到空项目Weapon1、Weapon2、Weapon3中。并调整好模型位置,让摄像机显示的模型位置符合正常人的视角。完成以上准备工作后,玩家控制的角色Player应为图4-13所示。图4-13玩家控制角色Player层级图4.2.2敌人模块首先导入资源包中的敌人模型放置于场景中,对该模型添加rigidbody和charactercontroller,根据游戏引擎的特性,角色的动作是绑定在角色模型上的,游戏角色上不同片段的动画剪辑存储着所有可使用于角色动画或简单动画的动画数据。在角色模型导出设置中设置动画选项后,再导入到Unity3D引擎中,通过程序控制在一定条件下播放动画剪辑来达到游戏角色的动作表现效果。在Patrol状态下,AI角色会根据一定的路径播放行走动画,同时通过程序控制角色的位移和旋转,这样就达到了巡逻的行为;在Attack状态下,AI角色会播放攻击动画[15]。实现敌人巡逻的功能如下图4-14所示。functionStart(){if(target==null&&GameObject.FindWithTag("Player"))target=GameObject.FindWithTag("Player").transform;Patrol();}functionPatrol(){varcurWayPoint=AutoWayPoint.FindClosest(transform.position);while(true){varwaypointPosition=curWayPoint.transform.position;if(Vector3.Distance(waypointPosition,transform.position)0){//重置生成时间Enemy_Time=Random.Range(0,5f);Instantiate(Enemy);Enemy_Max--;}}else{return;}text=GameObject.Find("Canvas/Score").GetComponent();text.text="得分:"Score;}publicvoidEnemyDestoryed(){Enemy_Max;Score=100;}图4-15创建敌人的方法敌人的攻击方式与主角类似,使用ai脚本发送信息控制模型播放动画并攻击正前方物体,其脚本也十分相似,在之后的武器开火模块会做详细介绍。4.3  弹药模块4.3.1  弹药和弹药箱模型根据需要,使用3dmax制作一个弹药箱的模型,如图4-16所示。多边形建模技术是三维建模技术中比较常见的一种建模方式。现实世界中的很多物体都可以看成是由基本的几何体进行变形和细分得来的。多边形建模就是基于简单的长方体、圆柱体、球和其它一些几何体,用添加线,点来进行细分,面挤出,边挤出等三维建模手法来完成模型的创建。多边形建模技术的优点在于它能很快的把目标模型的大体轮廓勾勒出来,对于精度要求比较低的模型来讲,甚至可可以经过简单的几次变形就可以达到想要的效果[17]。图4-16弹药箱的制作由于需要和虚拟世界的弹药箱产生交互,所以需要做角色和物体之间的碰撞 检测 工程第三方检测合同工程防雷检测合同植筋拉拔检测方案传感器技术课后答案检测机构通用要求培训 ,当角色碰触到虚拟世界中的弹药箱后,弹药箱做出响应。在Unity中,做碰撞检测有三种方法。第一种是碰撞器,第二种是触发器,最后一种是射线检测。碰撞器是一群组件,它包含了很多种类,比如BoxCollider,CapsuleCollider等,这些碰撞器应用场合不同,但作用基本一样。触发器则表示当碰撞发生时触发事件。添加触发器只需要在Collider的监视器窗口勾选IsTrigger选项即可[18]。给导入的弹药箱模型给它添加刚体属性rigidbody和碰撞器capsulecollider,弹药箱有着以下功能特性:弹药箱悬浮在地面上,沿着y轴按照一定速度旋转;弹药箱被玩家拾取后会消失,增加玩家后备弹匣40发步枪子弹,播放一个枪械装弹的音效;敌人被玩家击败后,地面上会掉落一个弹药箱。将rigidbody的iskinematic勾选,使其不受到力的作用。添加好audiosource,将换弹的音效插入进去。为其添加ammobox的脚本。在敌人预制体上为的伤害接收脚本中设置其死亡时销毁该敌人,使用一个刚体替换它。实现上述功能的代码如图4-17、4-18所示。voidUpdate() {//控制弹药箱沿着y轴旋转transform.Rotate(newVector3(0,rotationSpeed*Time.deltaTime,0));}voidOnTriggerEnter(Collidercol){if(col.gameObject.tag=="Player"){//对步枪发送获得弹药的信息GameObject.Find("Weapon1").SendMessage("GetAmmo");AudioSource.PlayClipAtPoint(reload,transform.position);Destroy(gameObject);}}图4-17 实现弹药箱旋转、发送获得弹药信息functionDetonate(){Destroy(gameObject);if(deadReplacement){vardead:Rigidbody=Instantiate(deadReplacement,transform.position,transform.rotation);dead.GetComponent.().velocity=GetComponent.().velocity;dead.angularVelocity=GetComponent.().angularVelocity;}varemitter:ParticleEmitter=GetComponentInChildren(ParticleEmitter);if(emitter){emitter.emit=false;emitter.transform.parent=null;}}图4-18 敌人死亡时替换为弹药箱代码4.3.2弹药安装弹药安装实现以下功能:若弹夹内子弹为满,则无法填装;若子弹全部打空,则无法填装。玩家开火时装弹,则优先装弹,装弹完毕后才能继续开火。对于玩家开火时优先装弹这一功能,使用变量控制是否发送开火信息来实现。令变量Reloading初始值为false,若玩家未装弹则可以正常开火,若玩家在开火时装弹,则令变量为true。此时无法发送开火信息,具体实现如下图4-19所示。if(!Reloading){if(Input.GetButton("Fire1")){BroadcastMessage("fire");    }}if(Input.GetButton("Reload")){Reloading=true;BroadcastMessage("test");}图4-19使用变量控制是否向武器子类发送信息若接收到按下Reload的命令,需要测试是否满足装弹条件。将当前弹夹的子弹数量与每个弹夹的子弹数进行比较,若相同则直接返回,不进行装弹操作;若后备弹夹已经全部打空,也直接返回。实现上述测试功能的代码如下图4-20所示。functiontest(){//若弹夹为满,不进行填装if(bulletsLeft==bulletsPerClip)return;//弹匣为空,不进行填装elseif(ClipsLeft==0)return;else//若满足条件则向当前项和子类发送reload命令BroadcastMessage("reload");}图4-20 测试装弹条件是否满足当满足上述条件后,向当前项和子类发送装弹命令。当前项控制武器装弹,而子类关联了动画脚本,接收到装弹信息后会控制模型播放动画。步枪和手枪装弹方式类似,区别在于每个弹夹子弹数不同,而小刀是不需要弹药的,不设置子弹等属性。步枪装弹时,要考虑到特殊事件,即当前弹夹和后备弹夹子弹数之和都没有40发的情况。此时若装弹,将后备弹夹与当前弹夹子弹数相加即可。除此之外的情况,只需让当前弹夹子弹数重新等于40,并让后备弹夹减去添加进去的子弹数。其具体装弹过程如下图4-21所示。functionreload(){if(ClipsLeft>=40||ClipsLeftbulletsLeft>40){  ClipsLeft=ClipsLeft-bulletsPerClipbulletsLeft;bulletsLeft=bulletsPerClip;}else{bulletsLeft=bulletsLeftClipsLeft;ClipsLeft=0; }}图4-21步枪武器装弹函数4.4  武器模块4.4.1  武器开火实现武器的开火流程与装弹类似,都是从父类接收到信息后完成一系列的操作。此外,开火音效和装弹音效分别在Weapon1和Rifle上,创建audiosource组件后将相应的音频文件添加进去。整个步枪武器模块发送和接收信息的流程如图4-22所示。武器开火实现的原理是添加一个作用力到正前方。而这个方向是相对的,如果关联了步枪开火脚本的Empty项Weapon1的方向是歪的,那游戏角色所发射的子弹也是偏离准星的,所以需要把weapon1的Transform中的属性Reset,令它的位置属性xyz均为0。实现射击功能的方法如图4-23所示。图4-22步枪接收开火信息流程图functionfire(){if(bulletsLeft==0)return;if(Time.time-fireRate>nextFireTime)nextFireTime=Time.time-Time.deltaTime;// 在开火率允许的范围内一直开火while(nextFireTime
本文档为【基于Unity3d的第一人称射击游戏的实现(2)】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_321635
暂无简介~
格式:doc
大小:103KB
软件:Word
页数:53
分类:
上传时间:2022-08-22
浏览量:13