河北工业大学U3D实验报告.docx
《河北工业大学U3D实验报告.docx》由会员分享,可在线阅读,更多相关《河北工业大学U3D实验报告.docx(51页珍藏版)》请在冰豆网上搜索。
河北工业大学U3D实验报告
计算机游戏程序设计
实验1-4报告
实验一GUI游戏界面的实现
一、实验目的与要求
1.熟悉及掌握GUI的高级控件,以及用法。
2.掌握GUI自定义皮肤用法
3.熟悉GUILayout的使用。
4.熟悉2D贴图的绘制和帧动画的实现方法。
二、实验原理及知识点
在游戏的整个开发过程中,游戏界面设计占据非常重要的地位。
因为游戏启动后,第一个映入玩家眼帘的就是游戏的UI界面。
UI界面主要包括贴图,按钮和高级控件等。
通常游戏界面的展现方式有很多种,大多数都由自定义图形界面组成。
Unity为开发者提供了一套非常完善的图形化界面引擎,它包括常见的游戏窗口、文本框、输入框、拖动条、按钮、贴图框等,无论是做软件还是做游戏,都可以很方便地使用。
另外,Unity提供了界面自定义皮肤的功能。
控件不仅可以使用默认的皮肤,还可以自定义皮肤,自定义皮肤不仅可以美化游戏界面,还可以提升游戏品质。
Unity游戏界面主要由GUI完成。
在本章中,我们将使用JavaScript脚本向读者详细介绍Unity中有关GUI界面的所有高级控件。
1.GUI高级控件
系统高级UI控件已经成为游戏开发中不可缺少的一部分,高级界面由系统提供,所以运行效率要远远高于低级界面(高级界面为系统实现,低级界面为自己手动实现)。
拿按钮控件来说吧,不使用系统提供的按钮控件,我们也可以使用低级界面模拟实现按钮的功能。
不过,低级界面实现的“按钮”没有高级界面实现的效率高,但是低级界面制作的“按钮”比较灵活,可以任意修改。
GUI高级控件的种类非常繁多,包括标签、按钮、输入框和拖动条等。
他们可用于任何游戏或软件的界面研发。
GUI高级控件的应用也非常广泛,比如网络游戏中输入账号与密码的提示框,通关游戏后上传游戏积分的按钮,创建角色时输入的角色信息等。
下面将分别向读者介绍GUI高级控件的相关用法。
1.1Label控件
使用Label控件(标签控件),可以在游戏界面中以文本的形式展示出一段字符串信息。
使用Label控件,我们不仅可以输入字符串,还可以贴图。
1.2Button控件
在开发中,Button控件(按钮控件)是十分常见的控件之一,可以用来判断用户在程序中的一些操作行为,比如对话框中的“确定”和“取消”按钮。
按钮共有3个基本状态组成:
未点击状态、击中状态、点击后状态。
一般情况下,游戏界面的按钮只监听“未点击状态”和“点击后状态”。
按照展现方式,按钮可以分为两种:
“普通按钮”和“图片按钮”。
普通按钮为系统默认显示的按钮,而图片按钮可以设定按钮的背景图案。
1.3TextField控件
TextField控件主要用于监听用户输入的信息,其应用非常普遍,比如在游戏登陆界面中,玩家输入用户名和密码后,点击“确认”按钮判断其输入是否正确,或者游戏通关后填写胜利者姓名与输入相关的游戏信息等。
一般情况下,使用GUI.TextField()方法显示输入框,该方法的返回值为用户输入的字符串信息。
使用GUI.PasswordField()方法,可以将用户输入的信息显示为任意字符串,一般在输入密码时将密码以“****”的形式显示。
后面的参数“*”【0】用来将输入的字符串显示为“*****”。
1.4Slider控件
Slider控件由滑块和滑动条组成。
使用Slider控件,可以计算出滑块在滑动过程中占整个滑动条的比例。
如果滑动条的整体长度为100,则滑块滑动的范围就是0至100。
按照展示方式,滑动条可分为两种:
一种为水平滑动条(HorizontalSlider),另一种为垂直滑动条(VerticalSlider),它们之间的用法完全相同。
在开发中,我们常使用滑动条来调节音量或者颜色等。
1.5ScrollView控件
如果游戏界面中的GUI控件过多,超出了屏幕的显示范围,就需要使用ScrollView控件来完成它的展示效果。
ScrollView控件可设定一个滚动显示区域。
如果横向或纵向的GUI控件超出了其显示区域。
视图下方或者右方将会出现滚动条。
在开发中使用ScrollView控件的情况非常普遍,比如如果游戏中帮助信息或者关于信息过长,就可以使用滚动条来查看相关信息。
1.6群组控件(GroupView控件)
群组视图(GroupView控件)可将多个视图全部放在一个群组当中。
将视图添加进群组当中后,群组中任何视图的坐标都是相对坐标,它是相对群组视图左上角的坐标。
修改群组视图坐标后,群组中所有视图的坐标都会跟着修改。
推荐使用群组视图来制作游戏界面,因为设备的屏幕尺寸不同,这样做可以避免对坐标进行多次修改的麻烦。
1.7窗口
窗口在游戏开发中并不陌生,所有视图都需要依赖窗口来显示,我们可以把窗口理解为视图的父类。
前面我们介绍了各式各样的游戏视图,它们都属于窗口的子类。
游戏界面可以由若干个窗口组成,窗口又由若干个视图组成。
创建窗口时需要设定它的显示区域,在窗口中可以添加任意组件,前提是组件的显示区域必须在窗口当中,否则无法显示。
另外,窗口中所有控件的坐标均采取相对坐标,相对窗口左上角的坐标。
1.9GUISkin
通过之前章节的学习,我想大家已经掌握了Unity大部分的GUI控件,但是直接使用这些控件开发游戏还远远不够,因为系统默认的界面实在过于粗糙与单调。
为了让自己的游戏界面活灵活现,我们需要使用GUISkin为控件添加一个漂亮的皮肤。
2GUILayout游戏界面布局
游戏界面的制作效果有很多中,有复杂绚丽的界面,也有简单明了的界面,而设计方式的仁者见仁,智者见智。
在跨平台游戏界面开发中,最麻烦的事就是各个平台的分辨率不一样,甚至相同平台的分辨率也不一样,这无疑给移植造成非常大的麻烦。
因此,在制作游戏界面时,使用绝对坐标值是相当危险的一件事。
因为如果跨平台移植的话,分辨率发生了改变,开发者就得为其重新设计坐标,这在开发效率上将大打折扣。
为了避免后期对坐标重新进行计算,前期制作界面时可以考虑自适应屏幕布局,GUI为开发者提供了游戏布局的概念,并且在布局的过程中所有的坐标点都是对称坐标,所以使用GUI游戏界面布局来制作界面将更有效地实现自适应屏幕。
2.1GUI与GUILayout的区别
通过之前的学习,我相信大家对GUI应该并不陌生了,那么GUILayout是什么东西呢?
它是游戏界面的布局。
从命名中就可以看到这两个东西非常相像,但是在使用过程中两者还是存在一定区别的。
使用GUI绘制控件的时候,需要设置控件的Rect()方法,也就是说需要设定控件的整体显示区域。
这样设置的控件非常不灵活,因为它的坐标以及大小已经固定死了,这是如果控件中的内容长度发生改变,就会直接影响展示效果。
例如,在界面中绘制一个按钮时,按钮中的显示文本刚好填充在整个按钮当中,如果动态加长文本的显示长度,就会超出按钮的显示范围,使按钮控件变得不伦不类。
我们需要制作控件的自适应,所以不能使用Rect()方法固定控件的显示区域,而是需要使用界面布局制作界面。
使用GUILayout来制作界面,可以很方便的为我们解决上述难题。
使用GUI制作界面的时候,需要给每一个控件设定显示区域,系统会自动帮我们计算控件的显示区域,并且保证他们不会重合。
(注意之前介绍的大部分GUI控件都可以使用GUILayout进行绘制)
2.2线性布局
线性布局是以线性连续排列的形式将GUI控件有规律的显示在屏幕中,共分为两种:
一种为水平线性布局,另一种为垂直线性布局。
默认的界面是以垂直线性布局的方式来排列。
创建水平线性布局时,首先需要使用BeginHorizontal()方法,然后将控件添加至线性布局当中,最后使用EndHorizontal()方法来结束当前线性布局。
而如果使用垂直线性布局,则需要使用BeginVertical()方法与EndVertical()方法。
无论是水平线性布局还是垂直线性布局,都可以使用嵌套的形式来制作游戏界面,也就是说,父类布局中可以继续嵌套一个子类布局,子类布局完全受父类布局的限制。
善用布局之间的嵌套,可以方便我们制作更为复杂的游戏界面。
2.3控件偏移
布局与布局之间都是以一种线性方式紧密排列的,无法直接修改布局当中两个相连控件的距离,为了解决这个问题,就需要使用空间偏移。
在控件中使用Space()方法可以设置控件之间的偏移量。
32D贴图与帧动画
2D贴图好比在屏幕中绘制了一张静态图片,其绘制方式有两种,第一种由GUI绘制,第二种是将贴图以材质的形式绘制在游戏对象中,在本节中,我们将着重介绍第一种方式。
帧动画的实现原理就是使用若干张静态图片以一定的时间一帧一帧地在屏幕中切换播放,好比在屏幕中预先设定一个现实动画的区域。
然后将图片在这个现实区域中频繁切换播放。
由于绘制的图片有规律的切换播放,给人们带来了视觉的假象,感觉就像播放动画一样。
3.1绘制贴图
要在屏幕中绘制一张静态贴图,需要使用GUI.DrawTextture()方法,该方法可设定图片的显示位置、缩放比例和渲染混合等,该方法的原型如下:
其中第一个参数表示图片的绘制区域,第二个参数表示绘制图片的图像,第3个参数表示图片的缩放模式,第四个参数表示的是否开启图片混合模式,第五个参数表示图片缩放宽高的比例。
在Project视图中将需要加载的图片存储在根目录“Resources”中。
需要说明的是,一定要将加载的图片保存在“Resources”文件夹中,否则程序将无法识别。
Resources.Load()方法和Resources.LoadAll()方法的参数均为资源文件夹的完整路径,只不过前者返回的事读取的资源对象,后者返回的是资源对象的数组。
3.2绘制动画
本节中我们开始学习帧动画的绘制。
首先需要一组帧动画的资源,在这里我们选择一套2D人物四宫格行走图,在绘制帧动画之前,我们需要学习帧动画的绘制原理:
首先需要在屏幕中设定一个显示区域,然后将动画中的每一个帧动画按照固定的时间在这个区域中按顺序切换,继而实现动画的播放。
这里我们使用程序将动画资源存储在动画数组当中,然后设定动画的刷新时间,每次刷新动画时将在原有的显示区域中绘制下一帧图片,到了最后一帧则从第一帧重新开始,以此类推你。
3.3实例——人物移动
结合2D帧动画的绘制原理,本节我们将制作一个游戏实例,效果如图3.4所示。
在屏幕中共绘制了四个按钮,通过点击这四个按钮来控制主角的移动,并且播放主角在对应方向上的行走的动画。
程序需要监听用户出发的按钮来切换动画方向,比如当用户点击“向上”按钮时,将播放主角向上走的动画。
我们使用x、y全局变量来记录当前主角的坐标,上下行走为加减x坐标,左右行走为加减y坐标,最后根据主角的x、y坐标来绘制但前动画在屏幕中的位置,从而实现控制主角向四个方向行走。
4本部分内容小结
本部分首先介绍了Unity中GUI界面的相关组件以及自定义皮肤的实现方式,其中每一个GUI高级组件都配备了一个小例子供读者学习;然后介绍了GUI与GUILayout的区别,已介入和使用GUILayout布局来制作界面;接着介绍了使用GUI绘制2D贴图与动画,以及如何控制主角移动的游戏实例;最后通过制作一个游戏主界面,回顾了前面所学的游戏界面的相关内容。
请大家认真阅读本章内容,打好游戏界面设计的基础,为后面深入学习做好准备。
三、实验内容及步骤
1.熟悉GUI高级控件,练习使用GUI的高级控件制作2~3个游戏界面。
2.练习使用GUI自定义皮肤,实现游戏界面的字体,背景颜色等设置。
3.熟悉GUILayout的使用,联系使用GUILayout的水平线性布局和垂直线性布局,并加适当偏移。
4.熟悉2D贴图的绘制和帧动画的实现方法,练习在界面中绘制静态图片和动画。
代码如下:
#pragmastrict
varstr:
String;
varmm:
String;
functionStart(){}
functionUpdate(){}
functionOnGUI(){
GUI.BeginGroup(Rect(Screen.width/2-150,Screen.height/2-100,400,300));
GUI.Label(Rect(20,20,80,30),"菜单:
");
if(GUI.Button(Rect(100,40,60,20),"自动漫游")){
Application.LoadLevel("自动漫游");
}
if(GUI.Button(Rect(100,10,60,20),"音频播放")){
Application.LoadLevel("音频播放");
}
if(GUI.Button(Rect(100,70,60,20),"画线")){
Application.LoadLevel("画线");
}
if(GUI.Button(Rect(100,100,60,20),"视频播放")){
Application.LoadLevel("视频播放");
}
GUI.EndGroup();
}
实验二Unity游戏脚本
一、实验目的与要求
1.熟悉及掌握MonoDevelop脚本编辑器的使用方法。
2.Unity脚本的生命周期。
3.熟练使用脚本来操作游戏对象。
二、实验原理及知识点
Unity游戏脚本在整个游戏开发中可以说是关键要素,游戏对象之间任何逻辑的判断都需要通过脚本来完成。
如果说游戏贴图、模型资源的好坏决定一个游戏的视觉品味,那么脚本将直接决定这个游戏的内在质量,决定这个游戏好玩与否。
游戏脚本与其他游戏组件用法相同,必须绑定在游戏对象中才能执行它的生命周期。
Unity一共支持3种语言来编写脚本,分别是JavaScript、C#、Boo,这3种语言不分好坏,用哪一种来编写都可以达到同样目的。
从编程技巧与难度上来讲,JavaScript更容易上手一些,建议初学者使用JavaScript进行入门阶段学习,但是进阶阶段推荐使用C#语言来编写脚本,因为C#语言在编程思想上更符合Unity引擎的原理。
由于与传统语言相比,Boo语言的语法更为怪异,所以开发中几乎不会用到它。
1MonoDevelop脚本编辑器
Unity可部署在Windows与MacOSX梁总操作系统下,所以Unity需要一个跨平台的脚本编辑器。
MonoDevelop脚本编辑器并不是Unity公司所研发的。
它是一个开源项目,任何人或公司都可以使用。
由于该编辑器具有强大的跨平台功能,并且使用起来非常方便,所以很快被Unity公司作为核心脚本开发环境使用。
2Unity脚本的生命周期
Unity脚本从唤醒到销毁有着一套比较完善的生命周期,添加任何脚本都必须遵守自身生命周期法则。
下面介绍一下生命周期中有系统自身调用的几个比较重要的方法。
functionAwake(){}。
脚本唤醒,此方法为系统执行的第一个方法,用于脚本的初始化,在脚本的生命周期中只执行一次。
functionStart(){}。
此方法在Awake()方法之后、Update()方法之前执行,并且只执行一次。
functionUpdate(){}。
正常更新,用于更新逻辑。
此方法每帧都会由系统自动调用一次。
functionLateUpdate(){}。
推迟更新,此方法在Update()方法执行完后调用,同样每一帧都调用。
functionFixedUpdate(){}。
固定更新,固定更新常用于移动模型等操作。
因为固定更新每一帧调用的时间相隔都是完全一样的,所以模型的移动过程会比较均匀。
functionOnGUI(){}。
绘制界面。
这个方法大家应该不会陌生,因为在第3章中已经做过很多例子了。
它和Update()方法一样,每一帧都在调用,只是它是用来绘制界面的。
functionOnDestroy(){}。
当前脚本销毁时调用。
3利用脚本来操作游戏对象
在Unity场景中出现的所有实体都属于游戏对象,比如系统自带的立方体、球体以及由美工制作的.Fbx游戏模型等。
游戏对象与脚本联系非常紧密,因为游戏对象之间的一切交互都需要使用脚本来完成。
下面我们开始学习如何使用脚本来操作游戏对象。
使用脚本来调用游戏对象的方式有两种,它们是:
可以将脚本绑定在一个游戏对象身上,也可以在代码中动态绑定脚本和删除脚本。
任何一个游戏对象都可以同时绑定多条游戏脚本,并且这些脚本互不干涉,各自完成各自的生命周期。
3.1创建游戏对象
创建游戏对象的方式共有一下两种。
第一种为将模型预先放入Hierarchy视图中,然后在场景视图中任意拖动该模型在3D世界中的位置,运行游戏后该模型就会出现在Game视图中。
第二种为在代码中根据条件动态创建与删除游戏对象,这种处理方式灵活性比较高。
3.2获取游戏对象
在脚本中获取游戏对象的方式一共有三种:
第一种为通过对象名称获取,第二种为通过标签(tag)获取单个游戏对象,第三种为通过相同标签获取多组游戏对象。
3.3添加组件与修改组件
新创建的游戏对象本身并不具备任何特性,为了让它具备一些功能,就必须给其添加游戏组件。
游戏组件的种类非常多,常见的游戏组件有脚本类、网格类、粒子类、物理类、声音类和渲染类等。
本节中我们将学习如何在代码中添加与修改游戏组件。
添加游戏组件时,可以使用AddComponent()方法。
由于组件自身没有对应的删除方法,需要使用父类执行Object.Destroy()方法才能删除它,其中该方法的参数为需要删除的游戏对象或游戏组件。
在删除某一游戏对象时,将连带该对象中的所有组件一并删除。
3.4克隆游戏对象
克隆游戏对象与创建游戏对象在效果的呈现方式是完全一样的,但是从执行效率上来讲,克隆游戏对象的效率要高。
使用脚本克隆游戏对象在游戏中应用非常广泛,常用于一些完全相同并且数量庞大的游戏对象,比如游戏中发射的子弹对象,每一颗子弹对象是完全一样的,每一次发射子弹都会新克隆一个子弹对象,并且让克隆的子弹对象完成自己的生命周期。
在代码中,需要使用Instantiate()方法克隆游戏对象。
4用脚本来控制对象的变换
在3D世界中,任何一个游戏对象在创建的时候都会附带Transform(变换)组建,并且该组建是无法删除的。
Transform面板中一共包含3个属性:
Position(位置)、Rotation(旋转)和Scale(缩放)。
在场景中使用移动工具来拖动和旋转模型,即可直接在Transform面板中看到编辑后的值,此外也可在Transform面板的编辑框中修改对象的位置、旋转方式和缩放的数值。
4.1改变游戏对象的位置
在3D世界中,任何一个模型的三维坐标都保存在Vector3容器中,该容器将记录模型在x轴、y轴和z轴方向的坐标。
一旦在程序中修改该模型在Vector3容器中的坐标,那么Scene视图中模型的位置将发生改变。
4.2旋转游戏对象
模型的旋转方式可分为2种:
第一种为自身旋转,意思是模型沿着自己的x轴,y轴或z轴方向旋转;第二种为围绕旋转,意思是模型围绕着坐标系中的抹一点或摸一个游戏对象整体来做旋转。
下面简要介绍一下经常会用到的一些重要方法和参数。
Øtransform.Rotate():
该方法用于设置模型绕自身旋转,起参数为旋转的速度与旋转的方向。
Øtransform.RRotateAround():
该方法用于设置模型围绕某一个点旋转。
ØTime.deltaTime:
用于记录上一帧所消耗的时间,这里用作模型旋转的速度系数。
ØVector3.right:
x轴方向。
ØVector3.up:
y轴方向。
ØVector3.forward:
z轴方向。
当模型绕自身旋转时,可以使用objCube.transform.Rotate()方法,当模型围绕抹一点旋转时,则使用objCube.transform.RotateAround()方法。
4.3平移游戏对象
平移的含义是模型在原有位置的基础上继续移动,在代码中可以使用transform.Translate()方法来实现,此方法的唯一参数为平移模型的方向。
4.4缩放游戏对象
在Unity中,可以通过代码动态缩放游戏中的模型。
主要有三种缩放方式:
沿x轴缩放、沿y轴缩放、沿z轴缩放。
每个轴都有自身的缩放洗漱,模型默认的缩放系数是1,就是模型原有大小,因此要在程序中实现模型的缩放,只需要动态修改模型的缩放系数即可。
三、实验内容及步骤
1.熟悉MonoDevelop脚本编辑器的使用方法,联系实现脚本调试。
设置默认脚本的打开方式:
脚本调试:
2.编程实现创建游戏对象(立方体,球体),给游戏对象命名,改变颜色,添加刚体组件。
源代码:
usingUnityEngine;
usingSystem.Collections;
publicclassduixiang:
MonoBehaviour{
//Usethisforinitialization
voidStart(){
}
//Updateiscalledonceperframe
voidUpdate(){
}
voidOnGUI(){
if(GUILayout.Button("创建立方体",GUILayout.Height(50)))
{
GameObjectobjCube=GameObject.CreatePrimitive(PrimitiveType.Cube);
objCube.AddComponent();
objCube.name="Cube";
objCube.renderer.material.color=Color.blue;
objCube.transform.position=newVector3(0.0f,10.0f,0.0f);
}
if(GUILayout.Button("创建球体",GUILayout.Height(50)))
{
GameObjectobjSphere=GameObject.CreatePrimitive(PrimitiveType.Sphere);
objSphere.AddComponent();
objSphere.name="Sphere";
objSphere.renderer.material.color=Color.red;
objSphere.transform.position=newVector3(0.0f,10.0f,0.0f);
}
}
}
3.分别通过名称、标签获得游戏对象,通过标签获得多个游戏对象。
通过名称:
源代码:
publicclassfind:
MonoBehaviour{
privateGameObjectobjCube;
privateGameObjectobjSphere;
privateboolisCubeRoate=false;
privateboolisSphereRoate=false;
privatestringCubeInfo="旋转立方体";
privatestringSphereInfo="旋转球体";
//Usethisforinitialization
voidStart(){
objCube=GameObject.Find("Cube");