Unity应用开发实战案例
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

2.3 实现过程

2.3.1 GUI设置

(1)首先,创建Plane,如图2-1所示。接着,将图片BG拖曳至Plane上,图片拖曳如图2-2所示。

图2-1 创建Plane

图2-2 图片拖曳

(2)调整相机位置及旋转角度,并将相机属性从“Perspective”(透视方式)改为“Orthographic”(正交方式)(“Inspector”→“Camera”→“Projection”→“Orthographic”),修改相机属性如图2-3所示。

图2-3 修改相机属性

(3)将Plane调整到全屏大小,如图2-4所示。

图2-4 将Plane调整到全屏大小

(4)发现无法实现屏幕大小自适应,于是换另一种方法。首先,创建一个空物体:“Create”→“Create Empty”,并命名为BG,创建空物体如图2-5所示。

图2-5 创建空物体

(5)选中BG,在Inspector面板中单击“Add Component”,在搜索框输入“GUI”后,选择“GUI Texture”,如图2-6所示添加GUI Texture属性。

图2-6 添加GUI Texture属性

(6)将图片BG拖曳至Texture右侧参数框中,如图2-7所示。

图2-7 图片拖曳

(7)若此时在 Game 窗口(游戏界面)中未显示出背景图片,则需修改 BG对应的Inspector参数,如图2-8所示。

图2-8 修改BG对应的Inspector参数

(8)设置完参数后,若Game窗口中仍未显示背景图片,则需在主相机(Main Camera)的Inspector面板下单击“Add Component”,在搜索框内搜索“GUI”并选择“GUI Layer”,如图2-9所示添加GUI Layer。

图2-9 添加GUI Layer

(9)调节背景图片的颜色和亮度,如图2-10所示。

图2-10 调节背景图片的颜色和亮度

(10)创建 GUI Skin,并使用自定义类型(Custom Style),将其重命名为MyGUISkin,创建过程为依次单击“Assets”→“Create”→“GUI Skin”,添加按钮如图2-11所示。

图2-11 添加按钮

(11)在Inspector面板中将Custom Styles的按钮数目设置成3个,并设置3个按钮的背景。如图2-12所示设置“游戏开始”按钮 start_btn,如图2-13所示设置“游戏设置”按钮 setting_btn,如图2-14所示设置“游戏退出”按钮exit_btn。

图2-12 设置“游戏开始”按钮start_btn

图2-13 设置“游戏设置”按钮setting_btn

图2-14 设置“游戏退出”按钮exit_btn

此时单击“运行”还不能出现3个按钮,因它们只是游戏资源,还不是游戏对象。

在这种情况下,一般不直接在 Unity 中将游戏资源拖曳过去使其变成游戏对象,而是使用脚本进行控制,在Game窗口中实时渲染,此时Scene窗口中没有内容。

(12)创建C#脚本程序menu.cs,实现按钮的显示,将脚本赋给Main Camera。

① 先在脚本中实例化GUISkin。

Public GUISkinMyGUISkin;

② 定义3个按钮。

RectstartRect;

RectsettingRect;

RectexitRect;

在start()中设置按钮的高度和宽度,也就是对应贴图文件的高度和宽度。

startRect.depth=MyGUISkin.GetStyle("start_btn").normal.background.heigh;

startRect.width=MyGUISkin.GetStyle("start_btn").normal.background.width;

③ 在OnGUI()中生成按钮,并且设置其大小和位置。注意:OnGUI()函数前需要加一行“GUI.skin=MyGUISkin;”,否则,if语句会报错,找不到“start_btn”。

if(GUI.Button(newRect(0f,Screen.height*0.45f,startRect.width,startRect.height),"","start_btn"))

前面只是实现按钮的显示,接下来需要设置单击按钮后的触发效果。

if(GUI.Button(new Rect (new Rect (0f,Screen.height * 0.45f, startRect.width,startRect.height),"","start_btn"),"","start_btn"))

{

Debug.Log("start_btn被按下");

}

if(GUI.Button(new Rect(0f,Screen.height*0.65f,

settingRect.width ,settingRect.height),"","setting_btn"))

{

Debug.Log("setting_btn被按下");

}

if(GUI.Button(new Rect(0f,Screen.height*0.85f,exitRect.width,exitRect.height),"","exit_btn"))

{

Debug.Log("exit_btn被按下");

}

2.3.2 设置第二组按钮

用同样方法设置第二组按钮(需要修改Inspector面板中的GUISkin设置),如图2-15所示。

图2-15 设置第二组按钮

设置后发现存在按钮重叠问题,这时就需要用布尔值来解决。设置布尔值bUI,在start()中给bUI赋true值,在OnGUI()中,使用if(bUI)来管理“游戏开始”“游戏设置”和“游戏退出”三个按钮,并且在单击“游戏设置”按钮后,给bUI赋false值。同时,使用if(!bUI)语句来管理“音乐开启”“音乐关闭”和“游戏退出”三个按钮,并且在单击“游戏退出”按钮后,给bUI赋true值。按照上述方法赋值后,再次演示时,两组按钮均可正常显示。

2.3.3 添加背景音乐

(1)创建声音源(Audio Source),命名为sound_BG,如图2-16所示添加背景音乐。

图2-16 添加背景音乐

(2)对应地,主相机自带一个 Audio Listenter(声音监听器)。(注意:一个场景中只能有一个 Audio Listenter,否则系统会报错。所以当再次添加相机时,需取消勾选Audio Listenter。)

(3)接下来需要赋给sound_BG的Audio Source一个背景声音文件,操作步骤是:依次选择“Assets”→“GameAssets”→“Sounds”→“strashnyi_les_muzyka”。选中文件“strashnyi_les_muzyka”并拖曳至对象sound_BG在Inspector面板中的Audio Clip参数框中。音效拖曳如图2-17所示。

(4)勾选“Play On Awake”和“Loop”选项,使背景音乐在启动时就开始循环播放,播放模式设置如图2-18所示。

图2-17 音效拖曳

图2-18 播放模式设置

(5)背景音乐什么时间开始?什么时间停止?具体的逻辑关系是:当程序启动时背景音乐开始,单击“游戏设置”按钮下的“音乐关闭”按钮后,停止播放。单击“音乐开启”按钮后,恢复背景音乐播放。

以上逻辑关系需通过编写脚本来实现。

以上脚本可以实现背景音乐播放、音乐关闭和音乐开启等功能。

2.3.4 添加按钮声音

(1)添加声音,创建Audio Source,命名为sound。需赋给sound的Audio Source一个声音文件,具体步骤是:依次选择“Assets”→“GameAssets”→“Sounds”→“dianji”,将文件dianji拖曳至对象sound在Inspector面板中的声音剪辑(Audio Clip)参数框中,音效拖曳如图2-19所示。

图2-19 音效拖曳

(2)为了使按钮声音在启动时不播放,而是通过脚本来控制播放,需取消勾选“Play On Awake”。设置后可在Assets菜单下选中文件“dianji”,在Inspector面板中进行测试,如图2-20所示设置播放模式。

图2-20 设置播放模式

(3)以下脚本代码可以控制按钮声音的播放:

//定义公共变量,按钮按下的声音

publicAudioSource sound;

在OnGUI()函数中,编写实现单击“游戏开始”按钮后,播放音乐的代码,即在“Debug.Log("start_btn被按下");”语句后,输入语句“sound.Play();”。

(4)在 Hierarchy 面板中选择 Main Camera 对象,将 sound 对象拖曳到Inspector面板中的Sound参数框中;将sound_BG对象拖曳到Inspector面板中的Sound_BG参数框中;将MyGUISkin脚本拖曳到Inspector面板中My GUI Skin参数框中。对象拖曳和脚本拖曳分别如图2-21和图2-22所示。

图2-21 对象拖曳

图2-22 脚本拖曳

(5)测试:单击“游戏开始”按钮后观察是否有音乐播放功能。若声音较小,则选中Hierarchy面板中的sound对象,在Inspector面板下调整3D Sound Settings中Min Distance的参数值,或查看sound对象的位置坐标和相机的位置坐标是否相差很大(也就是说Audio Source与Audio Listener不能距离太远)。

(6)按钮声音大小问题解决后,可以在OnGUI()函数中给每个按钮生成的 if 语句中加上“sound.Play();”语句。这样,单击每个按钮时都会产生相应的按键声音。

2.3.5 解决UI的自适应问题

在计算按钮的位置之前需要新增一个自定义函数ApplyVirtualScreen(),用该函数来实现屏幕自适应功能。

设置ApplyVirtualScreen()函数,通过缩放屏幕尺寸大小,解决屏幕自适应问题,并使第一组按钮显示出来。

创建好的界面效果图如图2-23所示。

图2-23 界面效果图

2.3.6 连接第二个场景

Menu界面做好后,创建第二个场景,命名为Factory。修改脚本文件menu.cs中的代码,在OnGUI()函数中“sound.Play();”语句后输入“Application.LoadLevel("factory");”语句,进行场景跳转测试。

2.3.7 解决转场问题

单击“游戏开始”按钮后,发现在按钮声音还未结束时就直接加载第二个场景;单击“游戏退出”按钮后,按钮声音还未播放完毕,就已经退出场景。出现这样的情况是由于同步加载问题,为解决此问题,应在menu.cs脚本中进行如下修改:

//定义两个布尔变量

//监听声音是否播放完

boolbPlay;

boolbexit;

在Update()函数中增加下列代码:

在OnGUI()函数的“游戏开始”“游戏退出”按钮单击语句中,增加下列代码:

经测试,发现问题得到解决。

2.3.8 搭建第二个场景

(1)进入新创建的Factory场景,并在Assets菜单中Game_Prefab目录下先将做好的地形MainGround拖曳至Hierarchy面板中(注意:预制体本身就具有位置坐标信息,若拖曳至Scence视图中,则会改变预制体原有的坐标信息。故应直接拖曳至 Hierarchy 面板中,这样,坐标信息就可以保持不变。必须先拖曳MainGround后,才能拖曳其他物体),场景搭建如图2-24所示。

图2-24 场景搭建

(2)在场景中添加一束平行光,使场景变亮。

2.3.9 拖曳地形

从Assets菜单中Game_Prefab目录下将其他模型拖曳至Hierarchy面板中,需将地形上移一点,使其与模型更加贴近。(其中 MainGround 已拖曳,FireHeavy_01、FireHeavy_01 1、FireHeavy_01 2这3个粒子系统,Lights(灯光),sound_qiang,PlayerControl和clouddome(动态云)先不拖曳。注意:所有预制体的位置都不能修改。)

2.3.10 设置动态云

选中动态云(clouddome)对象,在Inspector面板中单击“Remove Component”取消其脚本属性,动态云设置如图2-25所示。Inspector 面板中 whisps01下的Shader属性不变,为Particles/Additive,即粒子透明。

图2-25 动态云设置

2.3.11 制作天空盒

(1)依次选择菜单“Assets”→“GameAssets”→“MySky”,删除 MySky材质球。

(2)制作天空盒的6个面:制作6个纹理贴图对应天空盒的6个面,将其放到Assets文件夹中。在Assets文件夹中选择每一个贴图后,都需在Inspector面板中修改Wrap Mode后的循环模式为Clamp。否则,边缘的颜色将无法完美匹配。图片属性修改如图2-26所示。

图2-26 图片属性修改

(3)依次选择“Assets”→“Create”→“Material”选项创建一个新的材质,选中该材质资源,在Inspector面板中Shader属性后单击下拉菜单,选择“Skybox”→“6 Sided”,即将此材质设置成天空盒材质。创建材质如图2-27所示,修改材质属性如图2-28所示。

图2-27 创建材质

图2-28 修改材质属性

(4)天空盒贴图:只需分别将纹理贴图文件拖曳至天空盒的6个面即可,如图2-29所示制作天空盒表面。

图2-29 制作天空盒表面

(5)选中“Main Camera”,在Inspector面板中单击“Add Component”,在搜索框中输入“sky”并单击下方“Skybox”选项添加天空盒组件,如图2-30所示。

图2-30 添加天空盒组件

(6)将创建好的天空盒“MySky”拖曳至Custom Skybox参数框中,如图2-31所示。

图2-31 天空盒拖曳

2.3.12 动态云脚本控制

为了使动态云真正运动起来,需添加脚本文件 CloudDomeScript.cs,并将其绑定到clouddome上,调节scrollSpeed的值,将clouddome的Y轴坐标值调整到-700左右。相应的代码如下所示:

2.3.13 风车动画制作

风车旋转效果可通过动画控制或脚本控制方式实现。下面介绍风车动画的制作方式。

(1)依次单击Hierarchy面板中的“Structures”→“Vetryak”→“Vint”(风车风叶模型)选项。

(2)依次单击菜单中“Window”→“Animation”选项,如图2-32所示创建动画。

图2-32 创建动画

(3)在Animation面板中依次单击“Vint_Vetryak”→“Create New Clip…”选项建立动画文件,并命名为 myAniForFengche,如图2-33所示新建动画并命名。

图2-33 新建动画并命名

(4)单击“Add Property”按钮,选择“Transform”→“Rotation”选项(因为风车动画的实质就是风叶沿着Z轴旋转,故选择“Rotation”选项),如图2-34所示选择动画参数。

图2-34 选择动画参数

(5)单击“录制”按钮,设置初始帧,将风车风叶模型参数 Rotation.x、Rotation.y、Rotation.z的值均设置为0,如图2-35所示制作动画(一)。

图2-35 制作动画(一)

(6)移动白色线条到1:00或2:00位置,将该帧风车风叶模型参数Rotation.x、Rotation.y、Rotation.z的值分别设置为0、0、-360,如图2-36所示制作动画(二)。

图2-36 制作动画(二)

(7)再次单击“录制”按钮,停止录制。单击“运行”按钮,测试动画效果。

(8)关闭Animation窗口,即完成了动画设置。在Unity3D窗口中运行游戏,该模型将按设置的动画运行。

在关闭 Animation 窗口前,可以用鼠标右键单击“Vint:Rotation”后选择“Romove Properties”取消在模型上绑定的动画(另外两种方法是:① 选中该模型,在Unity3D菜单中依次选择“Component”→“Miscellmoues”→“Animation”后,将Assets下刚建立好的动画文件myAniForFengche拖曳至Inspector面板下的Animation参数框中;② 利用脚本控制Vint旋转并设置旋转速度。这两种方法能达到同样的效果),动画拖曳如图2-37所示。

图2-37 动画拖曳

(9)鸟飞的动画(Crow)

在Hierarchy面板中,名称为Crow的空物体下有Crow、Plane001、Plane002、Plane003这4个部分。其中,Crow是一个空物体,Plane001、Plane002、Plane003是3只鸟的模型。给鸟添加飞翔盘旋的效果,具体操作方法参照风车动画制作步骤。

2.3.14 加入灯光

从Assets菜单中将灯光“Lights”预制体拖曳到Hierarchy面板中,其中只有一束平行光,其他都是点光源,点光源用于实现不同地方的光线强弱不同的效果。

2.3.15 加入第三人称

加入PlayerControl模型(第三人称)步骤如下。

(1)该模型由 CameraControl 和 UniversalTrooperHD_Ruby 组成。其中,CameraControl中自带相机,UniversalTrooperHD_Ruby是实际人物模型。

(2)设置人物碰撞属性:选择Hierarchy面板中的UniversalTrooperHD_Ruby模型(依次选择菜单中“Component”→“Physics”→“Character Control”选项),给对象设置人物碰撞属性,调节半径(Radius)、高度、位置等属性。

(3)加入第三人称控制脚本:选择Hierarchy面板中的UniversalTrooperHD_Ruby模型(依次选择菜单中“Component”→“Scripts”→“Third Person Controller”选项),将已经导入的动画文件分别填充到Inspector面板中的Idle Animation、Walk Animation、Run Animation、Jump Pose Animation的动画填充栏,完成对该人物的动画设置。

(4)添加相机控制脚本:选择Hierarchy面板中的UniversalTrooperHD_Ruby模型,(依次选择菜单中“Component”→“Scripts”→“Third Person Camera”选项),此步骤完成后相机和人物就实现了绑定。

(5)为实现用鼠标控制人物移动的功能(键盘的“A”“S”“D”“W”键也可实现控制移动的功能),可将playercamer.js文件绑定到空物体“CameraControl”上,并通过如图2-38所示的对象拖曳将 Inspector 面板中的 Cam 参数赋值为UniversalTrooperHD_Ruby,将Target参数赋值为Main Camera。

图2-38 对象拖曳

测试运行时发现相机位置太低,为解决这一问题可单击空物体“CameraControl”,在Inspector面板中,将Offset参数的Y值修改为3~4。Max Distance和Min Distance分别表示相机与人物之间的最大距离和最小距离,可以按需调节。由于游戏中使用的是人物自带的相机,故需关闭原有的相机,且在人物自带的相机上添加天空盒。

至此,第三人称制作完成。

2.3.16 添加单击鼠标左键时的游戏音效

(1)创建脚本文件 player_sound.cs,并将其拖曳至 PlayerControl 模型上,Sound变量的名称可以与menu.cs中的公共变量名称一致。

(2)将菜单中“Assets”→“Game Prefab”下的预制体 sound_qiang 拖曳至PlayerControl模型的Inspector面板下对应的Sound变量上,其目的是在每次单击鼠标左键时,都基于预制体 sound_qiang 产生一个物体的实例化。预制体sound_qiang的创建的步骤如下。

① 建立一个空物体,命名为sound_qiang。

② 选择该空物体(依次单击菜单中“Component”→“Audio”→“Audio Source”选项),并将菜单“Assets”→“GameAsset”→“Sounds”下的音频文件“ak47_conversion_singleshot2”拖曳至Inspector面板中的AudioClip参数框中。将制作好的预制体sound_qiang 拖曳至Game_Prefab 文件夹中,这样预制体就设置好了,设置预制体如图2-39所示。

图2-39 设置预制体

脚本文件中Input.GetMouseButton(0)对应的是单击鼠标左键,在Unity3D中,依次选择菜单中“Edit”→“Project Setting”→“Input”→“Axis”选项可以查看到。

这时实现的效果是每单击一次鼠标左键,发出一声AK47的枪声音效,通常设置参数为time>3。若感觉枪声音效播放速度太快,则增大time参数。

由于预制体 sound_qiang 一直增加,需要再增加一个脚本文件 life.cs 来控制预制体sound_qiang实例化所产生对象的生命周期。单击预制体sound_qiang,可以看到其对应的Inspector面板,再从“Assets”菜单的“Game Script”目录中将life.cs拖曳至预制体sound_qiang的Inspector面板中,设置时间值。

在非最大化窗口的前提下运行测试,观察有life.cs脚本文件时和没有此脚本文件时,在Hierarchy面板中预制体的产生与消失情况。

2.3.17 设置动画声源

作品基本制作完成,演示发现以下问题:当人物移动到风车附近时,风车转动的声音较大,但当人物移动到其他地方时声音却很小。这时需要调节 Audio Source参数,依次选择“Structures”→“Vetryak”,将Audio Source最大距离值设置为30.193。

2.3.18 发布.exe格式文件

在Unity3D编译环境下运行时,单击“退出”按钮后,发现此操作无应答,这是因为“Application.Quit()”语句只针对.exe格式文件运行时才起作用。发布本游戏后,测试能正常运行。至此,此作品制作完毕。