unity3d_v3.x中文快速入门教程


强大的跨平台 3D 游戏开发工具 ——Unity3D 其实本书早就应该面世了的,由于期间牵涉到了 Unity3D 这款软 件的版本不断更新与升级,我的教程也随之改了又改,书也就一拖再 拖的耽搁了下来。不过还好的是 Unity3D 最新的正式版并没有让我们 失望,其强大的游戏制作功能已经达到让人膛目结舌的地步。尤其是 它在 3.0 里面制作那款第一人称战争游戏,画质效果丝毫不逊色于当 下十分流行的《穿越火线》、《战地之王》等等的游戏。下图为 Demo 中的截图效果: Unity3D的官方网站:http://unity3d.com Unity3D的下载地址:http://unity3d.com/unity/download/ 下载好之后,您必须到它官方网站注册一个邮箱,才能获得 30 天试 用。如果您觉得对这款软件满意,还可在购买之后继续使用。其中购 买 pro 版本的 Unity3D,会获得更多的功能。 一、 Unity3D 的基本界面介绍 场景面板:该面板为 Unity3D 的编辑面板;您可以将您所有的模型、 灯光、以及其他材质对象拖放到该场景中。构建游戏中所能呈现景象。 动画面板:与场景面板不同,该面板是用来渲染场景面板中景象的。 该面板不能用作编辑,但却可以呈现完整的动画效果。 层次清单栏:该面板栏主要功能是显示放在场景面板中所有的物体对 象。 项目文件栏:该面板栏主要功能是显示该项目文件中的所有资源列 表。除了模型、材质、字体等,还包括该项目的各个场景文件。 对象属性栏:该面板栏会呈现出任何对象的所固有的属性,包括三维 坐标、旋转量、缩放大小、脚本的变量和对象等等。 场景调整工具:可改变您在编辑过程中的场景视角、物体世界坐标和 本地坐标的更换、物体法线中心的位子,以及物体在场景中的坐标位 置,缩放大小等等。 下面我重点详解一下菜单栏: 菜单栏中包含有八个菜单选项:分别是 File【文件】Edit【编辑】As sets【资源】 GameObject【游戏对象】Component【组件】Terrain【地 形】 W indow【窗口】Help(帮助) 。其各自又有自己的子菜单: 主菜单 包含的子菜单 File【文件】 New Scene【新建场景】 Open Scene【打开场景】 Save Scene 【保存场景】 Save Scene as… 【场景另存为…】 New Project… 【新建工程文件】 Open Project… 【打开工程文件】 Save Project… 【保存工程文件】 Build Settings… 【创建设置】(这里指创建游戏设置) Build & R un 【创建并运行】(这里指创建并运行游戏) Exit 【退出】 Edit【编辑】 Undo 【撤销】 Redo 【重复】 Cut 【剪切】 Copy 【拷贝】 Paste 【粘贴】 Duplicate 【复制】 Delete 【删除】 Frame selected 【当前镜头移动到所选的物体前】 Select All 【选择全部】 Preferences 【首选参数设置】 Play 【播放】 Pause 【暂停】 Step 【步骤】 Load selection 【载入所选】 Save selection 【存储所选】 Project settings 【工程文件设置】(包含:可执行文件 E XE 图标设置,画面抗锯齿功能设置等) Render settings 【渲染设置】(如果您觉得整体画面的 色彩质量不尽人意,可在此处进行调节) Graphics emulation 【图形仿真】(主要是配合一些图形 加速器的处理) Network emulation 【网络仿真】(可选择相应的网络类 型进行仿真) Snap settings 【临时环境】 Assets ( 资源) Reimport 【重新导入】 Create 【创建】(包含:文件夹、材质、脚本等等) Show in Explor 【显示项目资源所在的文件夹】 Open【打开】 Import New Asset... 【导入新的资源】 Refresh 【刷新】 Import Package...【导入资源包】 Export Package... 【导出资源包】 Select Dependencies 【选择相关】 Export ogg file 【导出 OGG 文件】 Reimport All 【重新导入所有】 Sync V isualStudio Project 【与 VS 项目同步】 GameObject 【游戏项目】 Create Other 【创建其他组件】 Center On Children 【子物体归位到父物体中心点】 Make Parent 【创建父集】 Clear Parent 【取消父集】 Apply Changes T o Prefab 【应用变更为预置】 Move T o V iew 【移动物体到视窗的中心点】 Align W ith V iew 【移动物体与视窗对齐】 Align V iew to Selec ted 【移动视窗与物体对齐】 Component(组件) Mesh 【网络】 Particles 【粒子系统】(能打造出非常棒的流体效果) Physics 【物理系统】(可使物体带有对应的物理属性) Audio 【音频】(可创建声音源和声音的听者) Rendering 【渲染】 Miscellaneous 【杂项】 Scripts 【脚本】(Unity 内置的一些功能很强大的脚本) Camera-Control 【摄像机控制】 Terrain(地形) Create Terrain 【创建地形】 Import Heightm ap - Raw ... 【导入高度图】 Export Heightm ap - Raw ... 【导出高度图】 Set Resolution... 【设置分辨率】 Create Lightmap... 【创建光影图】 Mass Place T rees... 【批量种植树】 Flatten Heightmap... 【展平高度图】 Refresh T ree and Detai l Prot otypes 【刷新树及预置细 节】 Window(窗口) Next Window 【下个窗口】 Previous Window 【前一个窗口】 Layouts 【布局】 Scene 【场景窗口】 Game 【游戏窗口】 Inspector 【检视窗口】(这里主要指各个对象的属性) Hierarchy 【层次窗口】 Project 【工程窗口】 Animation 【动画窗口】(用于创建时间动画的面板) Profiler 【探查窗口】 Asset Server 【源服务器】 Console 【控制台】 Help(帮助) About Unity 【关于 Unity】 Enter se rial num ber 【输入序列号】 Unity Manual 【Unity 手册】 Reference Manual 【参考手册】 Scripting Manual 【脚本手册】 Unity Forum 【Unity 论坛】 Welcome Screen 【欢迎窗口】 Release Notes 【发行说明】 Report a Problem 【问题反馈】 二、Unity3D 的一个简单预览 每个 Unity3D 版本都会自带一个 demo 源文件。在 3.0 正式版中, 自带的 Demo 就是网上展示的那款强大的射击游戏。在一般情况下, 您只要第一次打开 Unity3D v3.0 就会看见自带的那个 demo 项目文 件。但如果 Unity3D 并没有打开这个项目文件,您可以在 Unity3D 里 的“File”菜单下点击“Open Project …”,在随后弹出的“Unity – P roject W izard”对话框中点击“Open Other… ”按钮,在“C:\Docum ents and Settings\A ll Users\Documents\Unity Projects ”这个路径下找 到项目文件夹“Bootcamp Dem o”,选择并打开它。打开项目之后, 在舞台场景面板中依然什么都没有显示的的话,请在 Project【项目文 件栏】双击场景文件 。稍等片刻之后,该舞台场景的所有 对象就可导入舞台场景面板中。导入成功之后效果如下图所示: 点击一下中间的播放按钮 做一下测试(如果您的机器配置不 是太高,可能等待的时间会稍长)。过了不一会,您就可以在 Game 【动画面板】中看到一个正在运行的射击游戏了。 在这个游戏场景中,您能看到比其他游戏还要细腻的游戏画面, 例如各个物体的实时阴影。 当然如果您的机器配置比较高,那您还可以点击“ESC”键来将 画质进一步调高。 我们将画面质量调高之前,和画面质量调高之后的效果做一下对 比,如下所示: 看看河水是不是真实了许多。 三、在 Unity3D 中创建一个山势地形图 第一步:打开 Unity3D 软件,它可能会自动载入上一次的“Bootcam p Demo ”项目文件。不管它,在软件打开之后点击“File”——>“O pen Project… ”,在弹出的“Unity – Project W izard”对话框中找到 “Project Lo cation:”输入创建项目的文件夹地址,或者点击后面的 “Browse…”选择一个文件夹地址(注:已创建 Unity3D 项目的文件 夹,不能当作新创建项目的文件夹来使用),然后在“Import t he fol lowing packages: ”中选择要导入的项目文件包,每个文件包都带有 一些插件功能,由于我们第一次创建项目文件,所以我们将所有的复 选框都打上勾。但这样做会使得 Unity3D 在开始加载的时候速度偏 慢,等以后我们大家对各个包的作用熟悉了,在创建 Unity3D 项目文 件的时候,我们只勾选需要使用到的包就可以了。 全部设置好之后,我们点击“Create”创建项目。 第二步:在创建一个新项目之后,我们会看见新项目的各个面板中, 只有 Project【项目文件栏】包含了“Standard Assets ”和“Standard Assets(Mobile)”两个文件夹,这两个文件夹里面装的是之前所导入 项目文件包里的所有文件。除此之外,其他版面都是空空如也。不要 紧万丈高楼平地起,咱们马上就利用文件包和系统功能来丰富各个面 板。首先我们点击菜单栏上的“Terrain”——>“Create T errain”创 建一个带有地形属性的平面。如图所示: 但我们发现 Game【动画面板】中依然没有任何画面。其实道理很简 单,就像演唱会的实况直播。您把场景全部搭建好了,演员请上场了, 但没有加上摄像机,电视机前面的观众有如何能够收到演出的信号 呢? 第三步:点击“GameObject”——>“Create Other ” ——>“Camer a”,在场景中创建一个摄像机,这时您就可以在 Game【动画面板】 中观看到摄像机所观察到的景象了。 下面我们来改变一下这个光秃秃的地面。 第四步:点击菜单栏上的“Terrain”——>“Set Resol ution…”弹出 “Set Heightm ap resolut ion”面板来调节地面的大小。在“Terrain Width”的后面将数字改成 500,然后再在“Terrain Length ”的后面 将数字改成 500,设置好之后点击“Set Resolution ”按钮来将原来的 地形改成 500*500 大小的地形。 第五步:在场景面板中选中刚才创建的地面对象“Terrain”,如果您 觉得场景中不是很好选择所需要的对象,那么您还可以在 Hierarchy 【层次清单栏】选中您所需的对象,该栏中包含了所有场景面板中的 物体对象。选中地面对象“Terrain”之后,我们会在 Inspector【属性 面板】中马上发现与之对应的属性,包含有:Position【坐标】、Rota tion【旋转量】、Scale【缩放尺寸】、以及地面对象固有的“Terrain(S cript)”和“Terrain Collider ”。如下图所示: 其中 这个像画笔一样的按钮,是用来改变 地面材质的。我们点击它之后,可以在下面找到 ,点 击“Edit T extures…”——>“Add T exture”来到“Add Te rrain Te xt ure”面板 。然后我们单击 后面的圆圈,就可以为地面添加您所喜欢的材质了。 选择好之后请点击“Add”按钮来填入新材质。添加材质之后的地面 如图所示: 如果您觉得这个地形的材质过于单调,那么您可以继续点击“Edit T extures…”——>“Add T exture”来添加第二个材质,然后在“Brus hes”中选择您想要的笔刷形状 ,接 着在场景面板中刷出新材质的区域范围。 第六步:点击 这三个按钮其中的一个,选择合适的笔刷, 在地形图中可以刷出高山的形状,如图所示: 如果您觉得现在山峰太高,或者说某处的山峰有些多余。您可以按住 Shift 键不放,用刚才的笔刷进行反向平刷。 第七步:接下来就是给地形种草和种树了。具体的种草按钮是 , 而种树按钮是 。而他们的设置方法与地形材质的设置方法十分雷 同,都是先点击 按钮来添加您所需要的花草或树木,然后 在场景面板中刷出您所需要的区域。如图所示: 这里大家需要注意一下,Unity3D 在编辑模式下为了节约资源,采取 了资源剔除的方法。如果您在利用笔刷“种草”的过程中,没有看到 您所“种”上去的草,这时您只需将画面拉近即可观察到效果。 第八步:点击 ,来设置地形上的风速、阴影等效果。 第九步:地形的所有效果已经设置完毕,但我们发觉在 Game【动画 面板】画面似乎很暗,这是由于没有加入灯光的缘故。点击“Game Object”——>“Create Other ”——>“Directional L ight”创建一个 太阳光。 太阳光和自身的位置没有多大的关系,只与自身的角度有关,这和我 们平时生活中的太阳光是一致的。所以为了让场景变得更亮,我们就 需要用到场景调整工具中的旋转按钮 来对太阳光进行旋转。当然 您也可以在属性面板中对它进行调节 。根据我们生活的常识,当太阳光 90°直射地面的时候,光线最强。调整之后效果如下: 这时的 Game【动画面板】画面是不是亮了许多? 第十步:为了让摄像机全方位的观察我们刚才所创建的场景,您可以 在 Project【项目文件栏】中找到 、 、 这三个脚本文件,并将他们依次拖放到场景中的摄像 机上面 。如果您 觉得 Project【项目文件栏】中的文件过多,不容易寻找这三个文件, 您还可以在 Project【项目文件栏】上方的搜索框输入他们的名字,进 行搜索 ,这样很快就能找到对应的文件 了。放置完毕之后,点击测试按钮 ,您就可以身临其境的在您刚 才创建的 Game【动画面板】中进行漫游了。用鼠标控制视角,用键 盘的方向键控制行走。 漫游的过程中,您可以清晰的看见您创建的草随微风缓缓摆动。 第十一步:再次点击测试按钮 ,退出动画模式。下面我们来为场 景加上蓝天和光照效果。 选中场景中的摄像机对象,然后点选菜单栏中的“Component” ——>“Rendering”——>“Skybox”为摄像机添加一个天空盒。添 加成功之后,您就能在摄像机的属性面板中找到刚才添加的天空盒了 。接着我们去 Project【项目文件栏】 找到“Standard Assets ”文件夹下的“Skyboxes”文件夹。这里面摆 放了许多关于天空的材质球,您只需要选中一个您喜爱的天空材质 球,并拖放给摄像机里的天空盒【Skyboxe】的材质属性【Custom S kybox】,就可让场景的天空布满这种材质效果。 选中场景中的光照对象“Directional light ”,然后在它的属性面 板中找到“Flare”,并点选它后面的圆圈 。在它弹出的“Select Flar e ”对话框中选中双击 这种光照效果 ,这样就可以使得您在动画模式中清 楚的看见太阳所在的位置。再运行一下动画 看看效果: 第十二步:为了让场景更加的逼真,我们还可以为场景添加光照阴影 效果。具体的做法如下:选中光照对象“Directional light ”,在它的 属性面板中找到“Shadow T ype”【阴影模式】,它默认的是“No Sh adows”【没有阴影】,您可以将它改成“Soft Shadows ”【软渲染阴影】 或是“Hard Shadows ”【硬件渲染阴影】。“Soft Shadows ”【软渲染阴 影】以消耗 CPU 的计算为代价来产生阴影效果,这种模式运行速度 较慢,但对于机器配置比较落后的使用者是唯一的选择。“Hard Sha dows”【硬件渲染阴影】可利用新一代 GPU 的显卡加速功能来为游戏 进行阴影效果的渲染处理,其运行速度比较快,渲染效果也比较理想。 但无论您选择哪一个选项,动画场景的物体都会相对于阳光产生阴影 效果。如图所示: 第十三步:所有的场景效果调试完毕,按下 Ctrl+S 来保存场景文件, 取名叫做“terrain”以便日后调用。如果保存成功,您会在您项目的 Project【项目文件栏】中看到一个这样的文件 。 四、 为地形添加水源、各种水流以及水下的模糊效果。 第一步:打开 Unity3D 软件并导入上一次的“firstUnity”项目文件。 由于我在上一次的地形创作中就已经在山峰之间制作了一块洼地,它 可以作为一个承载湖水的地方。如果您上次的创作并没有这样的地 形,那么请您重新创建一个山势地形图,就当作自己的一次练习吧。 在场景面板中点击 Y 方向的绿色箭头 切换到顶视图,这 样可以便于我们很快的找到洼地的所在地方。 然后用鼠标滚轮迅速的推进观测距离。 接着再到 Project【项目文件栏】找到“Standard Assets ”文件夹下的 “Water(Pro Only )”【仅限专业版使用,如果是非专业版请转到‘W ater(Basic)’】文件夹中,拖拽一个 Daylight W ater【白天光照效果 的水模型】到洼地的中央,并利用场景调整工具中的缩放工具 , 将水模型调整到合适的大小。 紧接着我们再点击场景面板中右上角的白色小方块 ,将视角 切换到透视图。 然后利用场景调整工具中的位移工具 ,将水模型调整到合适的高 度。 这时您只需在播放时,将摄像机移动到洼地这个地方就可以看见湖水 的效果了。 第二步:但这样的效果略显单调了一些,既然是山中泉水我们还得有 一些瀑布和溅起的浪花。为了节约时间,我们直接在 Project【项目文 件栏】上方的搜索框输入字符“water f ”,就可以查出如图所示的材 质和模型。 在这里面中,“Water Fountain ”是一个喷泉模型,“Water Surface Sp lash”是一个水面的飞溅模型,“WaterFall”是一个瀑布模型。我们先 拖入一个“WaterFall”到洼地,然后利用场景调整工具来调整它的位 置和角度。 这时的瀑布略显小了一些,我们可以先选中它,然后到它的属性面板 去调整成您想要的效果。 再接着我们在瀑布下的水面上方放置一个水面飞溅模型“Water Surf ace Splas h”。由于它的高度一定要和水面高度一致,所以我们先点选 水平面看看它 Y 轴的数字,然后在点选“Water Surface Splash ”到 它的属性面板中输入同样的 Y 轴数字,以确保它浮在水面上。紧接 着到它的属性面板中调整它的属性,让改模型变成您想要得到的效 果。 第三步:我运行一下游戏 ,然后将镜头移动到泉水的水面下。 大家会发现,水下的视觉和在平地上的视觉效果是完全一样的。这和 我们平时的生活现状是不相符的,所以我们还得做一下相应的调整。 首先点击“GameObject”——> “Create Other ”——> “Cube”创 建一个立方体,并运用场景调整工具将它调整到整个水洼的实体部 分。 (注:运用其他形体也可以,其主要是用来覆盖水洼的实体部分,以 用来和摄像机作碰撞检测,让摄像机的镜头变得模糊。)接着,确保 您创建的这个 Cube 是被选中状态,到它的属性面板中,将“Box Co llider”卷展栏中的“Is T rigger”复选框打上勾(如果这里不打勾, 这个立方体将作为一个实物,当摄像机撞上它时,就像撞上一堵墙, 无法通过) 。然后再将“Mesh Re nderer”卷展栏下的所有复选框全部点掉,使这个立方体只作为一个 形体存在,而不让它在场景中作出任何的显示渲染 。接着在属性面板的最上方将它的 名字由“Cube”更改为“WaterColler” ,再选中“T ag”的下拉框——>“Add T ag…”新添加一个“WaterColler”的标签 分类 。然将这个“WaterColler”水 洼碰撞体的 Tag 也改成“WaterColler” 。 第四步:在菜单栏中选中“Assets”——>“Create” ——>“JavaSc ript”新添加一个 JS 脚本。到 Project【项目文件栏】找到刚才新建的 JS 脚本 ,按下 F2 键更改它的名字为“Under WaterEffect”,并双击编辑它,输入如下代码: private var defaultFog = RenderSettings.fog; private var defaultFogColor = RenderSettings.f ogColor; private var defaultFogDensity = RenderSettings.fogDensity; private var defaultSkyb ox = RenderSettings.skybox; var noSkybox : Material; function OnT riggerStay (hit : Collider) { if (hit.gameObject.tag=="WaterColler"){ RenderSettings.fog = true; RenderSettings.fogColor = Color (0, 0.4, 0.7, 0.6); RenderSettings.fogDensity = 0.04; RenderSettings.skybox = noSkybox; } } function OnT riggerExit (hit : Collider) { if (hit.gameObject.tag=="WaterColler"){ RenderSettings.fog = defaultFog; RenderSettings.fogColor = defaultFogColor; RenderSettings.fogDensity = defaultF ogDensity; RenderSettings.skybox = defaultSkybox; } } 输入完毕,按 Ctrl+S 保存代码并关闭退出,然后将代码拖拽给摄像 机使用。重新运行一下游戏,将摄像机移动到水下,就可以看到一片 模糊的景象了。 在 Unity3D 中,关于水的设置是一门非常深的研究课程。Unity3D 群 里的“黑魔麟”、“模模糊糊”等都有比较深的造诣,但在这本书中我 并不作出过多的阐述,因为本人也在联系各位 U3D 高手们,打造一 本 U3D 的黄金书籍,这里大家先入个门。下面为各位高手们制作的 一些水效截图: 五、U3D 中脚本的简单概述 和前面的所学 3D 软件一样,U3D 作为一个类播放器的 3D 集成 软件有着良好的时间层级关系。比方说 Start ( )里面的语言,总是在 播放器初始化时执行一次,而后就不再执行。例如下面用 JS 写的一 个列子:在菜单栏上选中“Assets”——>“Create” ——>“JavaSc ript”。 function S tart () { print("Game is start"); } 将这段代码拖拽给 Hi erarchy【层次清单栏】中任意一个对象,您就 会在播放器刚开始播放的时候,在左下方的控制台面板中看到“Gam e is start ”这样一句话,证明您的 Game 播放器已经开始工作了。 (*注:这个控制台面板以后大家会经常使用到它,因为它可以用作您代码片段 的调试,以及您程序出错了的提示框,详细的提示您出错的原因所在。) 当然有了初始化函数,就一定会有我们的刷帧函数 Update(),该函数 内所有的代码会在播放器每播放一帧时执行,例如下面用 JS 写的一 个列子:在菜单栏上选中“Assets”——>“Create” ——>“JavaSc ript”。 function Update() { print(Time.time); } 该代码会在播放器每播放一帧的时候,显示游戏开始到现在所消耗的 时间值。 U3D 中有着非常强大的接口处理功能,您可以在代码中为对象 制定任意一个空接口用于和对应类型的对象进行交互,例如下面用 J S 写的一个列子:在菜单栏上选中“Assets”——>“Create” ——> “JavaScript”。 var AddSpeed =5; function Update () { transform.T ranslate(0, 0, AddSpeed); } 该代码为对象添加了一个在 Z 方向上的初始速度,如果在没有其 他外力的作用下,物体将一直沿着 Z 方向以 5 的速度行驶。并且当您 将这段代码拖拽给一个物体对象之后,它的这个初始速度可以作为一 个接口在它的属性面板中进行修改 。 除了数字作为接口外,接口还可以是对象,例如下面用 JS 写的一个 列子:在菜单栏上选中“Assets”——>“Create” ——>“JavaScrip t”。 var AddSpeed=5; //定义一个变换对象 cubeGO var cubeGO:T ransform; function Update () { //在逐帧播放的过程当中,一旦按下 G 键 cubeGO 就以 AddSpeed 速度,朝 Z 轴 方向运动 if(Input.GetKey(KeyCode.G)){ cubeGO.T ranslate(0,0,AddSpeed); } } 您可以将这段代码拖放给 Hierarchy【层次清单栏】中任意一个对象, 因为它在这里定义了一个 Transform 类接口对象 cubeGO,所以它几 乎与拖拽的对象无关。拖拽成功之后来到该物体的属性面板中,您可 以看到这样的一个属性卷展栏 ,cubeG O 的后面有个很明显未定义对象填写栏“None(Transform)”,然后我 们把想要使之运动的物体拖拽到这个上面来,如图所示: 当我们运行游戏时,只要按下“G”键就可以看到 Cube 作为“cube GO”的指代对象,朝着“Z”轴方向运动了。 六、Unity3D 中的 C# Script 编程的注意事项 也许您在学习U3D之前,已经是一位C#的编程高手了。但在U3 D中的C#并像真正的C#那般强大,在U3D的C#中必须全部继承自Mo noBehaviour,像这样的格式public class NewBehaviourScript : Mono Behaviour {...} 。下面为一段C# Script 完整代码: using System.Collections; using UnityEngine; public class NewBeh aviourScript : MonoBehaviour { IEnumerator Som eCoroutine () { yield return 0; yield return new WaitForSeconds (2); } } 除此之外它不支持空间命名,但官方说它们很有可能会在以后的 版本中支持这一功能。 在 U3D 中,JavaScript 和 C# Script 的编程效果近乎一样。只是 为了不同程序爱好者设立了不同的编程模式。并且 JavaScript 所编写 的代码对象可以和 C# Script 编写的代码对象交叉使用,并不发生任 何冲突。 七、 利用 MonoDevelop 编写代码,来和 U3D 协同作战。 和我们前面所学到的软件一样,U3D 同样有着一个为它提供强 大编程支持的脚本编辑器《MonoDevelop》。这个软件会在您安装 Un ity3D 3.0 的时候自动安装。您可以在计算机的开始菜单下的 Unity3 D 目录中找到这个软件,如图所示: 打开 MonoDevelop 之后,点击新建按钮 。直接单击“Unity”就可 以看到它所对应的几个编程语言,其中的 Unity Script 指的就是 Java Script。 同样的,在里面输入代码就会弹出相应的提示,使用起来比用 U3D 中的脚本编辑方便了许多。如图所示: 八、修改 MonoDevelop 编辑器为 U3D 的默认编辑器。 通常情况下 U3d 默认的编辑器都是“UniSciTE”,它用起来十分 轻巧快捷,就像记事本一样。 但如果要开发一些大型的项目,显然“UniSciTE”简单的功能就 不足以支撑它的工作了。但如果您每回在编辑脚本的时候,都去用 “MonoDevelop”一个一个的打开,又显得很麻烦。所以我们就要在 U3D 中做一些设置,让“MonoDevelop”成为默认的脚本编辑器。具 体的步骤是:在菜单栏中找到“Edit”——>“Preferences…”,在弹 出的“Unity Preferences”对话框中找到“External Script Editor”并将 它后面的下拉框选中为“Browse…” 浏览到我们“MonoDevelop” 可执行文件存放的地方。这个路径一般都和您 U3D 文件夹在一起, 比方说您的 U3D 安装在 D 盘的 Program Files 文件夹中,那么您可以 直接在这个路径“D:\Program Files\Unity\ MonoDevelop\bin”找到 “MonoDevelop.exe”这个文件。 设置好之后,重新在 U3D 中点选下脚本文件,发现已经能用 “MonoDevelop”软件打开了,但第一次打开的时候会稍显慢一点, 因为“MonoDevelop”要加载很多东西。效果如下图所示: (注:如果您是一个 C#和 Visual S tudio 忠实编程爱好者,你可以用 同样的方法来设置 Visual Studio 的软件的路径,让 Visual Studio 成为 U3D 的脚本默认编辑器。) 九、向 U3D 中导入外部模型 U3D 支持多种外部模型格式,但它并不是对每一种外部模型的 属性都支持。具体的支持参数,您可以对照如下列表: 网络 材质 动画 骨骼 Maya 的.mb 和.ma1 格式 √ √ √ √ 3D S tudio Max 的.max1 格式 √ √ √ √ Cheetah 3 D 的.jas1 格式 √ √ √ √ C inema 4D 的.c4d1 2 格式 √ √ √ √ Blender 1 格式 的.blend √ √ √ √ Carrara1 √ √ √ √ COLLADA √ √ √ √ Lightwave1 √ √ √ √ Auto desk FBX 的.dae 格式 √ √ √ √ X √ √ SI 5 的.x1 格式 √ √ SketchUp Pro1 √ √ Wings 3D 1 √ √ 3D S tudio 的.3ds 格式 √ Wavefront 的.obj 格式 √ Drawing InterchangeF iles 的.d √ xf 格式 下面的实例中,我们利用 3D M ax 来制作一个完整的动画,并导 出 FBX 的格式给 Unity3D 使用。 第一步:创建一个名为“Turret”的项目文件夹。然后打开 Unity3D 软件,选择“File”——>“New Project… ”创建一个新工程项目, 在项目路径中点击“Browse…”选择找到我们刚才的“Turret”文件 夹,并点选我们需要导入的包文件,然后点击“Create”来创建一个 Unity3D 是无法以非空的文 第二步:打开 3D Max 软件制作一个炮塔模型,并将制作好的模型保 存在“Turret”文件夹中的“Assets”【资源】文件夹下面。下图为 3 D Max 中的模型样图: 新的工程文件。(注:这个步骤千万不能乱,因为 件夹作为工程文件夹来创建项目的。) 为了保障模型在 U3D 中的显示效果,我们给模型添加一些光照,并 将添加了光照的模型渲染为烘焙贴图,这样可使得模型本身带有一些 明暗纹理效果。其烘焙贴图的方法请参看第三章的 3.8 小节,烘焙之 后的效果图如下所示: 烘焙完毕之后,按住 Ctrl+S 保存文件。 质贴 图文件了。 第三步:重新来到 Unity3D 的软件环境中,这时大家已经能在 Projec t【项目文件栏】看到我们刚才用 3D Max 导出的模型文件和材 接着利用我们前面章节中所学到知识,为场景文件添加地形和阳光。 然后在地形图上找一个合适的位置,将我们的炮塔拖拽上去。 但这样看着,似乎太小了一点。在改变外部模型的尺寸的时候,有一 个技巧,您不必在场景中修改它。而可以到该模型所在的属性面板中 去修改它的“Scale Factor ”大小。它的默认值是 0.01,我们在这里 将它改为 0. 1 ,并在属性面板的最下方找到“Apply”按钮,点击它 让模型尺寸在 U3D 中得到改变。 再来看看我们的炮塔,是不是雄壮了许多? 但是,我们并不赞同这样的模型导入方法。因为根据官方的说法,他 们建议您将做好的模型导出成为 FBX 格式的模型文件给 Unity3D 使 用。也许这样会使模型在 Unity3D 中的运行速度得以提高吧。所以说 我们还得回到 3D Max 的软件环境下面,做一下导出工作。 第四步:在 3D Max 中,点击 File【文件】——>export【导出】,将 模型文件导出为 FBX 文件,保存到 “Turret”文件夹中的“Assets” 【资源】文件夹下面。注意一下弹出的“FBX Export ”面板,这里 包含了模型动画、骨骼工具、材质等等一系列的导出设置。如果您没 有在模型中添入这些东西,就请您将不必要的复选框点掉。 第五步:回到 Unity 3D 的软件环境,在 Hierarchy【层次清单栏】中 选中原先的炮塔模型,按下 Delete 键将其删除。然后在 Project【项 目文件栏】中找到刚刚导入 FBX 模型,点击选中它,用前面修改模 型尺寸的方法来修改 FBX 模型的尺寸。然后将其放置在场景中合适 的位置上。 十、 预制对象 Prefab,及其它的调用方法。 还记得我们在第二章中对 Flash 的学习吗?如果您不想让某些物 体出现在舞台上,但您又想通过代码随时的来调用这些物体。就比方 说游戏中的炮弹或子弹这类似的物体。那我们就要先在 flash 的库中 创建一个这样的影片剪辑,但并不把它拖放到舞台上显示,然后用鼠 标的右键点击它,并在它的属性面板里面将“为 ActionScript 导出” 复选框打上钩,这便可以随时随刻的用代码将它调入或调出舞台了。 Unity3D 中同样有着类似的功能,但它和 flash 在用法上稍稍不 同。具体的做法是:在菜单栏中点选“Assets”——>“Create” — —>“Prefab”在 Project 【项目文件栏】中创建一个预制类对象 ,这时您会发现预制类对象前面的小方框是灰色的,这说 明它是一个空对象,如果您现在用代码调用它,您并不能看到任何的 东西。但如果您在 Project【项目文件栏】中向它拖入任意物体 ,那么你立马就可 以在调用“new prefab ”的地方看到这个被拖入的物体,并且看见“n ew prefab ”前面的图标变为了实际的蓝色 。 预置类对象“Prefab”就像一个空着的盒子,您可以为它填充任 何的东西,并利用代码在舞台上显示它。 十一、图形用户界面类 G.U .I 您在玩很多 3D 游戏的时候,不知是否注意到在游戏界面中,总 有一些图形和文字信息是不随着 3D 视觉的改变而改变的。这也是由 于游戏本身的要求所决定的,比方说英雄的生命值,聊天窗口的文字 信息等等。这一些不被改变的类就被称作 G.U.I。 下面我们一起在U3D中简单做两个G.U.I实例,来说明它的用法。 第一步:打开 Unity3D,它会自动导入上一次的工程项目。为了节省 篇幅,我们还是使用前面的“Turret”工程项目来做说明。假设我们 就现在的项目来做一个炮弹发射的游戏,想想我们都需要做写什么工 作?是不是应该在画面的一个角落显示炮弹填发的情况?就像大多 数 3D 游戏那样,您的魔法值在使用完毕之后需要一定恢复时间。 第二步:用 PhotoShop 制作弹药的填发时间图。并将它们全部保存为 PNG 文件到工程项目的“Assets”文件夹内。 上面为 PhotoShop 制作的填发时间图,一共 5 张。 第三步:回到 Unity3D 软件环境中,为了归类我们在 Project【项目文 件栏】中右键——>“Create” ——>“Folder”新建一个文件夹,并 按 F2 将其更名为“shortTime”,再将导入的五张图片拖入文件夹内。 第四步:在菜单栏中选中“GameObject”——>“Create Other ” — —>“GUI T exture”创建一个 GUI 图标,这时大家会在 Scene【场景 面板】中看到一个默认 Unity3D 的图标,如图所示: 在 Hierarchy【层次清单栏】选中它之后,来到它的属性面板中,点 击 Texture 后面的 来改变它的图标为我们刚导入弹药填充图标。再通 过属性面板中其他属性值的更改,得到图标最终的显示大小和显示位 置,如图所示: 第五步:在菜单栏中选中“GameObject”——>“Create Other ” — —>“GUI T ext”创建一个 GUI 文字在图标的旁边作为说明。其文字 输入、文字大小、文字样式等等也同样在它的属性面板中调节。 十二、怎样让 Unity3D 支持中文字体 在上一节当中,大家学习了 G.U.I 图形和文字的使用方法。 但细心一点的朋友可能会发现,在“GUI T ext”中输入中文是 完全没有作用的,这是由于现在 Unity3D 还不支持中文的缘故。但是, 这并不能影响我们对中文作品的开发。Unity3D 中可以将任意的字体 作为材质文件赋予“GUI T ext”,其中就包含中文字体。具体做法如 下: 第一步:将您需要的中文字体拷贝到项目文件中的“Assets”文件夹 内。 第二步:在菜单栏中选中“GameObject”——>“Create Other ” — —>“GUI T ext”创建一个 GUI 文字,然后在它的属性面板中找到“F ont”点选他后面的 ,将它的字体类型改为您刚才拷贝进来的那个字 体 ,接着在属性面板中找到“Text”后 面的输入框输入您想要的输入的中文字体。观察场景面板,得到如下 效果: 十三、制作炮塔的旋转 第一步:给炮塔的上半部分添加一个旋转函数,使得炮塔随着鼠标在 X 方向上的移动而移动。在 Project【项目文件栏】中右键——>“Cr eate” ——>“JavaScript”新建一个 JavaScript 函数,并按 F2 将其更 名为“turretRotate”,然后输入如下代码。 var speed : float = 20.0; // 旋转速度 function Update(){ // 这里乘以 Time.deltaTime 函数是为了使旋转效果更加的平滑。 trans form.Rotate(Vector3(0, 0, Input.GetAxis("Mouse X")) * T ime.deltaTi me * speed); } 点选场景面板中的炮塔,找到炮塔上半部分所对应的对象,如图: 接着将刚才的“turretRotate.Js”文件拖拽给这个对象。 第二步:选中摄像机对象“Camera”,点选菜单栏中的“Component” ——>“Camera-Control”——>“Smooth Follow ”为摄像机添加一个 平滑的跟随代码,但这里并没有设置跟随对象。 第三步:继续选中摄像机对象,在它属性面板中找到“Smooth Follo w(Script)”卷展栏下的“Target”,然后将炮塔上半身对象拖放给它。 第四步:点击测试按钮 ,试着移动下鼠标看看炮塔的旋转效果。 摄像机随着炮塔的旋转而旋转,而 GUI 图标和 GUI 文字一直在左上 方,效果很不错。 十四、 制作炮弹的射击和爆炸效果 第一步:点击菜单栏的“GameObject”——>“Create Other ” ——> “Sphere”创建一个球体模型,并利用场景调整工具将其调整到和炮 口差不多的大小。 第二步:找两张金属材质的贴图,第一张为基本 RGB 贴图,第二张 为普通显示贴图。 图一 图二 这样做是为了一会在给物体赋予材质时,让它有立体的感觉。您也可 以只给物体找一张贴图材质。找到想要的材质贴图之后,将它们拷贝 到项目文件夹中“Assets”文件夹内。 第三步:选中刚才的球体模型,在它的属性面板中找到材质球下拉选 项框 。将它的渲染模式改为“Bumpe d Dif fuse”,紧接着将深色的材质贴图拖放给第一个材质框,将浅色 的材质贴图拖放给第二个材质框。 得到一个带有材质感的炮弹,如图所示: 第四步:在菜单栏中点选“Assets”——>“Create” ——>“Prefab” 创建一个预制类对象,并按下 F2 键更改它的名字为“Shot”,然后将 球体模型模型拖入到预制对象中,并删除场景面板中的炮弹。 但这时的球体模型仅仅是在外观上有了炮弹的样子,我们还得让它有 炮弹一样的物理特性。接着在菜单栏中点选“Component”——>“P hysics” ——>“Rigidbody”为炮弹添加一个刚体属性。 第五步:在菜单栏中点选“GameObject” ——>“Create Empty ”创 建一个空对象放置在炮口,作为一会炮弹发射的起始点。按下 F2 将 其更名为“FirePoint”。然后在 Hierarchy【层次清单栏】中,把“Fir ePoint”拖到炮塔上半身的旋转对象中去,这样可以使得它和炮塔一 起旋转。 第六步:为炮弹创建一个发射函数。在 Project【项目文件栏】中右键 ——>“Create” ——>“JavaScript”,创建好之后按下 F2 将其更名 为“open fire ”。然后双击该文件,输入如下代码: //定义一个变换对象 FirePoint 作为发射点对象的代码的接口 var FirePo int:Transform; //定义一个刚体对象 Bullet 作为炮弹对象的代码接口 var Bullet:Rigidbody; function Update () { //当鼠标左键按下的时候,就在场景中创建一枚炮弹,并发射它 if(Input.GetMouseButtonDown(0)){ var clone:R igidbody; //重新实例化对象 clone,让它的坐标位置和方向与发射点对象的一致。 clone = Instantiate(Bullet,FireP oint.position,FirePoint.rotation); //实例化完毕,让炮弹以 100 的速度朝前发射。 clone.velocity = transform .TransformDirection(Vector3.forward*100); } } 输入完毕之后,将该代码拖拽给 Hierarchy【层次清单栏】中的发射 点对象“FirePoint”,然后我们会在属性面板中的“FirePoint”接口和 “Bullet”接口对象为空。所以我们必须得把发射点对象“FirePoint” 和炮弹对象“shot”拖到两个对应的接口上。 第七步:按下测试按钮 看看效果。 大家会发现朝前发射的炮弹在碰到山体之后,都被弹了起来。所以说 此时的炮弹顶多只能算得上一个钢弹,它并不会爆炸。接下来我们还 要继续做出它爆炸的效果。 第八步:在 Project【项目文件栏】的查找框中输入“fireworks”关键 字,将查找到的 拖入到场景面板,您会看到一个动态的实时 爆炸火花。 接着确保该对象在选中状态,到它的属性面板中调节它的各个属性 值,直到达到您想要的效果为止。 第九步:在菜单栏中点选“Assets”——>“Create” ——>“Prefab” 创建一个预制类对象,并按下 F2 键更改它的名字为“boomPrefab”, 然后将这个爆炸火花拖入到预制对象中,并删除场景面板中的火花。 第十步:添加一段 JavaScript 代码,取名叫做“boom”,这段代码的 主要作用是给炮弹添加一个碰撞检测。如果炮弹碰撞到任何物体,就 让炮弹在舞台上消失,并在炮弹碰撞的地点加载爆炸火花的预制对 象。具体代码如下: //为爆炸火花创建一个接口 var boom Fire : T ransform; //函数判断物体是否与其他物体产生碰撞,一旦碰撞就执行里面的代码 function OnCollis ionStay(collision : Collis ion) { //实例化一个爆炸火花对象,摆放的职位是当前炮弹的位置,角度是炮弹的角度 Instantiate(boomFire,this.transform.position,this.transform.rotation); //删除掉碰撞的炮弹对象 Destroy(gameObject); } 输入完毕之后,保存该代码,并把这段代码拖放给炮弹预制对象“s hot”。并点选预制对象“shot”,在它的属性面板中找到刚才拖放给它 的“boom”卷展栏,然后将爆炸火花预制对象“boomPrefab”拖放 给它的接口“boomFire”。 然后运行一下游戏,看看效果。 大家已经很明显能看到爆炸之后产生的火花已经出来了,但它会一直 在那里闪烁,并不会消失。这严重的违背了现实生活景象,所以我们 还得为它加上一段时间限定消失代码。继续的创建 JavaScript 代码, 取名叫做“desBoom”,然后输入如下代码: //创建一个时间接口,这个时间接口不设定数值对象,默认以播放器开始起计算 var creation Time = T ime.time; // A wake 函数绝大多数被用于预制对象被调用时执行。这里主要意思是,当爆炸 火花被场景载入时,记录该火花的产生时间 function A wake(){ creationTime = T ime.time; } //这段代码的意思是:当前的时间大于爆炸火花产生的时间两秒以上,就让爆炸 火花对象消失。 function Update(){ if(Time.time > (cre ationTime+2)){ Destroy(gameObject); } } 输入完毕之后,将这段代码拖放给爆炸火花预制对象“boomPrefab”。 再次运行游戏,火花在爆炸产生 2 秒之后就自动消失了。 第十一步:为爆炸添加声音。这个过程十分的简单,只需您在网络上 找寻一个您认为合适的声音,并将这段声音文件添加入项目文件夹的 “Assets”内。并在 Project【项目文件栏】中,将其拖放给爆炸火花 的预制对象“boomPrefab”,这样声音文件就可以和火花同时产生了。 如果您觉得声音需要做适当的调节,例如“是否在预制对象产生时播 放?”、“声音是否需要循环播放?还是只播放一次?”等等这些问题。 您都可以在选中预制对象之后,在它的属性面板中找到声音的调节卷 展栏,对它进行调节。 我简单介绍一下这个面板: Play On A wake:打勾就意味着在预制对象调用之初进行播放。不打 勾的话,就需要您在代码里用 audio.play()函数来激活。 Loop:打勾就意味着让声音文件不断的重复播放,不打勾就只播放一 次。 Vo l u me:音量大小。 Pitch:音调,0.5 时很低沉,2 就已经算是高音了。 Min Distance :最小距离。 Max Distance :最大距离。 Rolloff Mode :衰减模式。您也可以在它下面的图形面板手动的调节。 但一般如果您选择的是第一种“Logarithmic Rollof f”模式,播放出 来的声音都会比较小。 第十二步:为炮管添加开炮的声音和喷出的火舌。 首先创建一个名为“explosionPrefab”的预制对象,然后到 Proj ect【项目文件栏】上的搜索栏上输入“Small explosion ”找到火舌对 象 ,并向舞台中拖拽一个该对象。之后点击搜索栏上的 ,还原原来的 Project【项目文件栏】,并将刚才的“Small explosio n”拖拽给预制对象“explosionPrefab”,并在场景面板中清除“Smal l explosion ”。 其次,在网络上查找一个开炮的声音文件,并将该声音文件拖拽 给预制对象“explosionPrefab”。 最后,双击“open fire.js ”文件,将代码修改成如下的样子。 var FirePo int:Transform; var Bullet:Rigidbody; //为火舌新增一个接口 var explosionPrefab:T ransform; function Update () { if(Input.GetMouseButtonDown(0)){ var clone:R igidbody; clone = Instantiate(Bullet,FireP oint.position,FirePoint.rotation); clone.velocity = transform .TransformDirection(Vector3.forward*100); //实例化一个火舌对象,火舌的位置为发射点的位置,方向为发射点的方向 Instantiate(explosionPrefab,FirePoint.position,FirePoint.rotation); } } 输入完毕,保存代码并退出。 第十三步:在 Hierarchy【层次清单栏】中选中发射点对象“FirePoin t”,然后在它的属性面板中找到“Explosion Prefab ”接口,并把火舌预 制对象“explosionPrefab”拖拽给这个接口。 第十四步:在菜单栏中选中“File”——>“Build Settings ”或者按下 Ctrl + Shift + B 键的组合来发布工程文件。 我简单介绍一下这个面板: Scenes In Build :这里面是要发布的场景文件列表。如果您发现有您 所需要的场景没有被列入该面板,那您可以点击“Add Current ”按 钮来为该列表添入新的场景文件。后面的数值是场景的加载顺序,0 为最先被加载的主场景文件。 Platform:导出的文件格式。第一种是网页格式,第二种是 Window 下的 exe 文件格式,第三种是微软手机操作系统的格式,第四种是 i Phone 使用的操作系统格式,第五种是 Xbox 格式,第六种是 PS3 格 式,第七种是游戏机 Wii 的格式。如果您没有购买正式的 U3D 专业 版软件,那么您只能发布前两种格式的文件。如果您已经购买了 U3 D 专业版软件,那么您还得注意第四种 IOS 格式的文件,必须在苹果 的 Mac OS X 操作系统下才能发布。 每一种发布的格式,又可以选择它们专属的发布属性,像网页格 式就规定了“Streamed”流媒体发布形式、“Offline Deployment ”离 线调度模式、“Debug Build ”调试开发模式。这些方法直接决定了网 页以什么形式来加载 U3D 文件,以及它们调试方法等等。 如果您对导出的文件,在播放器上有自己的个性化要求。那么您 还可以点击“Plater Settings… ”来对播放器的图标、项目开发的日期、 开发者或是公司的名字,等等进行设定。 最后我们一起来欣赏一下,该项目发布为桌面 EXE 游戏后,在 Window 下的表现。如图所示: 十五、 制作炮塔的填弹时间来限制开炮的时间间隔,并让 GUI 关联上这个时间。 在真实的炮塔射击中,不可能在炮管中一下子装入无限多颗炮 弹,让您没完没了的射击。一般情况,一个炮塔除了有一个控制射击 的瞄准人员,还得有一个负责装配弹药的填弹人员。 当炮塔将一枚炮弹射出之后,接下来必须由填弹人员迅速的为炮 管添加一枚新的弹药,射击手才能再次射击。由此炮塔在射击过程中 就产生了填弹时间。下面我们一起来看看怎么来实现这个填弹时间, 并让 GUI 动态的显示填弹状态图和百分比数字。 第一步:双击打开“open fire.js ”将代码修改一下,新增部分我会用 注释解释。 var FirePo int:Transform; var Bullet:Rigidbody; var explosionPrefab:T ransform; //创建一个开火的布尔变量,作为一个是否开火的开关使用 var openFireSwith= false; //创建填弹时间变量 var waitF ire = T ime.time; function Update () { if(Input.GetMouseButtonDown(0)){ //判断是否允许开火 if(openFireSwith){ //记录下开火的初始时间 waitFire = T ime.time; var clone:R igidbody; clone = Instantiate(Bullet,FireP oint.position,FirePoint.rotation); clone.velocity = transform .TransformDirection(Vector3.forward*15*poweCtrl.powe rValue); Instantiate(explosionPrefab,FirePoint.position,FirePoint.rotation); //将开火状态关闭 openFireSwith=false; } } //从开火之时算起,四秒钟之后再一次允许开火 if(Time.time > (waitF ire+4)){ openFireSwith=true; } } 第二步:将显示百分比数字的 GUI 更名为“zouGUI”,并为它配置一 段初始化代码“guiposition.js”,该代码的完整片段如下所示: function A wake(){ guiText.text="100%"; } 输入完毕之后,直接将代码拖拽给“zouGUI”。 第三步:将图形 GUI 对象更名为“shotTime_G”。 第四步:还记得前面我们导入的五种状态图形吗?现在我们为图形 G UI 书写动态加载各种状态的代码“shotTimeG.js”,完整代码如下所示: //创建各种状态的图形接口 var T00 : T exture2D; var T25 : T exture2D; var T50 : T exture2D; var T75 : T exture2D; var T100 : T exture2D; //初始化填弹时间,注意这里使用的是 static,证明它可以为全局所用 static var shotT ime = 100; function Update () { //初始化动态加载图形 GUI 的对象 var shotT ime_G=gameObject.Find("shotTime_G"); //图形 GUI 对象根据填弹时间的大小,来加载不同的状态图形 if(shotTime<=0) { shotT ime_G.guiTexture.texture = T00; return ; } else if(shotTime<50) { shotT ime_G.guiTexture.texture = T25; return ; } else if(shotTime<75) { shotT ime_G.guiTexture.texture = T50; return ; } else if(shotTime<99) { shotT ime_G.guiTexture.texture = T75; return ; } if(shotT ime>=99) { shotT ime_G.guiTexture.texture = T100; return ; } } 输入完毕之后,将该代码拖拽给摄像机对象 Camera。然后点选摄像 机对象,在它的状态栏中找到刚才的 shotTimeG(Script)卷展栏,并 将各个状态图形,一一的拖拽给代码上所对应的接口。如图所示: 第五步:重新打开“open fire.js ”修改代码,将这里的填弹时间与 G UI 显示的百分比和状态图关联上。请注意一下用方框框出来的代码 为新增添的代码: var FirePo int:Transform; var Bullet:Rigidbody; var explosionPrefab:T ransform; var openFireSwith= false; var waitF ire = T ime.time; function Update () { if(Input.GetMouseButtonDown(0)){ if(openFireSwith){ waitFire = T ime.time; var clone:R igidbody; clone = Instantiate(Bullet,FireP oint.position,FirePoint.rotation); clone.velocity = transform .TransformDirection(Vector3.forward*15*poweCtrl.powe rValue); Instantiate(explosionPrefab,FirePoint.position,FirePoint.rotation); openFireSwith=false; } } //首先判断是否在等待时间内 if(Time.time <= (waitFire+4) ){ //计算等待时间的大小,并折算成百分数赋给 shotTimeG 的静态变量 shotTime shotTimeG.shotTime = Mathf.Round((T ime.time-waitFire)*25); //计算等待时间的大小,并折算成百分比赋给 zouGUI 的文字参数。 GameObject.Find("zouGUI").guiText.text=Mathf.Round((Time.time-waitFire)*25) +"%"; } if(Time.time > (waitF ire+4)){ openFireSwith=true; } } 第六步:点击测试按钮 ,来看看效果。 十六、为炮塔制作假想敌人。 第一步:在菜单栏中选中“GameObject”——>“Create Other ” — —>“Cube”,在炮塔旁边创建一个正方体并将其更名为“tankBody”, 并用场景调整工具调整它的大小和位置。 第二步:创建一个 JS 脚本代码,并命名为“TankLife”,然后输入如 下代码,来作为“tankBody”的生命减少函数。 var tankL ife = 4; function OnCollis ionStay(collision : Collis ion) { //查找所有的碰撞体,如果发现有碰撞体的名字是"shot(Clone)",那么生命值减 1 f or (var conta ct : ContactPoin t in co llision.contacts) { // 这里要特别注意一下,判断炮弹的名字不是"shot"而是"shot(Clone)"" if (contact.otherCollider.name == "shot(Clone )") { if(tankLife>0) { tankLife --; } //当生命值小于 1,物体就消失 if(tankLife<1) { Destroy(gameObject); } } } } 输入完毕之后,将这段代码直接拖放给立方体对象“tankBody”。 第三步:点击测试按钮 ,用炮塔对准立方体射击。 连中四发炮弹之后,立方体果然消失了…… 十七、添加力量滑动条控制炮弹的发射力度。 第一步:创建一个名为“poweCtrl”JS 脚本代码,具体代码如下: //这里设置发炮力度变量 powerValue 的数值为 static,方便其他函数调用 static var powerV alue = 3.0; function OnGUI () { //这里设置键盘的两个键来控制滑块的滑动 if (Input.GetKeyDown (KeyCode.Q )&&powerValue>1)powerValue-=1; if (Input.GetKeyDown (KeyCode.E )&&powerValue<10)powerValue+=1; //这里将滑块的数量值付给发炮力度变量 powerValue //这里的 Rect (5, 100, 100, 30) 是设置滑块的位置及滑块的大小。 powerValue = GUI.Hori zontalSlider ( Rect (5 , 100, 100, 30), powerValue, 1.0, 1 0.0); } 创建完毕之后,将其拖拽给摄像机。 第二步:双击打开“open fire ”的 JS 脚本,然后在炮弹的初始化速 度变量框中加入“poweCtrl”的“powerValue”值来调控炮弹的发射 力度,代码如下: var FirePo int:Transform; …… function Update () { …… clone.velocity = transform.T ransformDirection(Vector3.forward*15*poweCtrl.pow erValue); …… } 第三步:点击测试按钮 ,最终效果如下: 十八、 多炮塔的镜头切换。 第一步:在 Hierarchy【层次清单栏】中选中炮塔对象,按下 Ctrl+D 复制同样的一个炮塔,将其拖到其它的位置。 第二步:在 Hierarchy【层次清单栏】中选中摄像机对象,在它的属 性面板中找到“Smooth Foll ow(Script)”卷展栏,并点击 展开它, 然后双击 来快速的打开“SmoothFollow”脚本,将其 中的代码完全拷贝出来。随后用鼠标右键点击“Smooth Follow (Scr ipt)”卷展栏——>“Remove Com ponent”将原有的摄像机跟随代码 从摄像机身上移除。 第三步:新建一个名为“followTurret”的 JS 脚本,然后将所有的代 码粘贴到这里面来,并稍微做一点修改。下面我贴出完整的代码,并 把改动的地方用线框框出来。 //将原来的跟随对象改为三个,其中的 target 是默认跟随对象,target1 和 target 2 是指定跟随对象。如果您有 N 个摄像机跟随对象,那么就请您在这里改为 N +1 个跟随对象。 var tar get : T ransform; var tar get1 : T ransform; var tar get2 : T ransform; var distance = 10.0; var height = 5.0; var heightDam ping = 2.0; var rotationDa mping = 3.0; function LateUpdate () { //这里设置,当您按下数字 2 键的时候,将跟随目标改为 target2 if (Input.GetKeyDown (KeyCode.Alpha2)) { target=target2; } //这里设置,当您按下数字 1 键的时候,将跟随目标改为 target1 if (Input.GetKeyDown (KeyCode.Alpha1)) { target=target1; } …… } 编辑完成之后,将该代码拖拽给摄像机对象。 第四步:在 Hierarchy【层次清单栏】中点选摄像机对象,继续找到 刚才添加的 展开它,然后将第一个炮塔的顶 部对象“mesh4”拖拽给“target”作为摄像机的起始默认跟踪对象, 接着再将第一个炮塔的顶部对象“mesh4”拖拽给“target1”作为数 字 1 键的选择跟踪对象,然后将第二个炮塔的顶部对象“mesh4”拖 拽给“target2”作为数字 2 键的选择跟踪对象。如图所示: 第五步:最后点击测试按钮 测试一下我们的小游戏。按下数字 1 和 2 键来回的切换两个炮塔的视角,然后多角度开炮轰击敌人吧。 小结:到这里我要为炮塔游戏做一个小小的总结了,因为本书篇幅的 关系,我不可能教大家做一个完整的多人在线坦克与炮塔攻防大战游 戏,但有兴趣的朋友可以到我的论坛或博客里面给我留言,咱们可以 一起来开发这款游戏。下面的章节中,我会为大家说说 U3D 中的角 色系统“Ragdoll”、如何创建游戏中的角色运动动画、还有粒子系统 “Particle System”。 十九、角色系统“Ragdoll”的概念及其运用。 角色系统【Ragdoll】也被一些人称作“布娃娃系统”,是 3D 制 作人员用来模拟真实人物物理运动状态的一个系统。下面我用一个简 单的例子来为大家说明一下。 第一步:打开 3DMax 创建一个人物模型,并且将整个模型做成一个 完整体。如果您的人物模型是由多个模型拼接而成,那么请您全选所 有的模型之后点击鼠标右键“转换为”——>“转换为可编辑网络”, 并到它们的修改面板中,进入顶点层级将相邻的面焊接起来。 第二步:在创建面板下,点选系统选择面板中的“Biped”来创建一 套人物骨骼。 第三步:在运动面板中 将“体形模式” 点为高亮。随后便利 用移动工具和缩放工具来调整骨骼的大小和位置,让骨骼的各个部位 和身体完全吻合。如果在对齐的过程中被模型遮住了骨骼,导致无法 看清对位,那么您可以按下 F3 键,将模型改为线条模式。 骨骼编辑完成之后,不要忘记到运动面板中 将“体形模式” 点 回原状态。 第四步:选中人体模型,在“修改面板”中为它添加一个“蒙皮”, 接着到“蒙皮”的骨骼面板中将人体骨骼全部添加进来。 第五步:创建一个名为“firstRagdoll”的项目文件夹,然后用 U3D 软件在该项目文件夹中新建一个工程项目。接着利用前面所学到的知 识,创建一个您理想中的地形和一个阳光。 第六步:回到 3DMax 软件中,先将整个模型渲染成纹理,烘焙的贴 图一定要同模型一并放在“firstRagdoll”项目文件夹的“Assets”文 件夹中。渲染成纹理的方法参看前面第三章 3.8 小节。导出 FBX 文 件到“firstRagdoll”项目文件夹中的“Assets”文件夹中。在导出的 过程中,一定要注意将导出骨骼选项选中,如图所示: 第七步:回到 U3D 的软件环境,将刚才导入的模型拖放一个到“场 景面板”中。接着点选菜单栏中的“GameObject”——>“Create Other” ——>“Ragdoll..”为模型创建一个角色系统。(*注:U3D 角色系统 的身体部位和它的英文名称并不对应,比方说它的“Knee”并不是指 膝盖,而是膝盖以下的小腿部分。下面我要重点说下各部位的记忆方 法) Root <—— 对应骨骼的根 Bip01 下面从左脚掌骨骼 Bip01 L Foot 往上数 3 个骨骼,对应角色系统中 Left Foot 往上数的 3 个骨骼。 Left Hips <—— Bip01 L Thigh Left Knee <—— Bip01 L Calf Left Foot<—— Bip01 L Foot 下面从右脚掌骨骼 Bip01 R Foot 往上数 3 个骨骼,对应角色系统中 Right Foot 往上数的 3 个骨骼。 Right Hips <—— Bip01 R Thigh Right Knee <—— Bip01 R Calf Right Foot<—— Bip01 R Foot 下面从左肩骨骼 Bip01 L UpperArm 往下数 2 个骨骼,对应角色系统 中 Left Arm 往下数的 2 个骨骼。 Left Arm <—— Bip01 L UpperArm Left Elbow <—— Bip01 L Forearm 下面从左肩骨骼 Bip01 R UpperArm 往下数 2 个骨骼,对应角色系统 中 Right Arm 往下数的 2 个骨骼。 Right Arm <—— Bip01 R UpperArm Right Elbow <—— Bip01 R Forearm 下面还有两块骨骼比较简单: Middle Spine <—— 第一脊髓骨骼 Bip01 Spine Head <—— Bip01 Head 全部对应好之后,将“Total Mass ”设置为 4,并点击创建按钮 。为了大家更便于理解,我再展示一下人体解析图: 第八步:点击测试按钮 测试一下角色系统。大家会发现人体模型 在没有添加如何力的情况下倒在了地上,并且姿势随作用力的方向随 机摆放。如图所示: 二十、怎样在游戏中为人物添加各种运动动画。 在我们日常玩的游戏当中。经常会碰见人物在游戏中做出行走、 跑步、跳跃等各种动作。很可惜的是在U3D中,这些动作并不依赖于 角色系统,但在U3D的官方网站上有一个高级人物运动系统的源文 件,大家有兴趣可以下载下来研究一下。网址是: http://unity3d.com/support/resources/unity-extensions/locomotion-ik.html 。下面我将为大家简单讲述一下,如何在Unity3D中实现人物根据指 令来做出各种动作。 第一步:打开 3DMax 以及我们上次创作出来的人物模型。在时间轴 上 0-19 帧制作人物的站立动画,在 20-60 帧制作人物的行走动画, 在 61-100 帧制作人物的跳跃动画。制作完毕之后,将动画模型导出 到“firstRagdoll”项目文件夹的“Assets”文件夹中,并另外取一个 名字叫做“moveTest.fbx”。 第二步:打开 Unity3D 软件,到 Project【项目文件栏】中选中刚刚导 入进来的“moveTest ”,并在它的属性面板中找到 ,点击后面的加号对动画进行切割。 我为大家详细解说下这里面的东西: Name:剪裁动画的片段的名字,就拿这个列子来说吧。我根据每个 动画片不同作用,将它们分别命名为“idle”【空闲】、“Go”【行走】、 “Jump”【跳跃】。 Star:该剪裁动画所开始的帧。 End:该剪裁动画所结束的帧。 WrapMode:循环模式,该选择框一共有五种模式“Default”(默认模 式的效果几乎和‘Once’模式的一样) ,“Once”(该模式让影片剪 辑播放完之后停在最后一帧),“Loop”(该模式可让这段影片剪辑从 开始帧到结束帧,不断的重复循环播放), “PingPong”(乒乓模式, 该模式顾名思义就是让影片剪辑从开始帧到结束帧来回的播放), “ClampForever”(让影片剪辑播放到最后一帧,然后永远停在那一 帧,直到下一个动画开始播放。) Loop:该复选框一旦被打勾,会自动产生一个从最后一帧到第一帧平 滑过度的帧,对于“Loop”循环模式下的动画尤为有效。 第三步:拖拽一个“moveTest”的模型到舞台中去,点掉属性面板中 的 不让模型动画在创建之初播放。然后到菜单栏 中选中“Component”——>“Character”——“Character Motor”给 模型添加一个人物控制器,接着到属性面板中的 调节人物控制器的轮廓、高度等信息,正好使 得角色控制器能够完整的框住模型。 接着到菜单栏中选中“Component”——>“Character”——“FPS Input Controller”给模型添加一个移动控制器,该控制器可以控制模型的前 后左右随键盘的方向键移动。再接着到菜单栏中选中“Component” ——>“Camera- Control”——“Mouse Look” 给模型添加一个旋转 控制器,由于我们只希望模型左右旋转,所以还得请您到模型属性面 板的“Mouse Look”卷展栏中将“Axes”选择为“MouseX”,然后将 其他的有关 Y 属性的值都调节为零,如图所示: 第四步:选中摄像机对象“Camera”,并到菜单栏中选中“Component” ——>“Camera- Control”——“Smooth Follow”给摄像机添加一个 跟随组件,在它的属性面板中找到 卷展栏, 并将我们的模型对象拖拽给 ,如图: 然后可以一边点击测试按钮,一边调节 卷展 栏里的各个属性值,直到调整到您觉得一个满意的跟随效果为止。 第五步:创建一个 JS 脚本,并且取名为“moveAnimationControl”。 用来控制模型在运动中对应的播放各种运动动画。具体的代码如下所 示: function Start () { //将跳跃的动画层级设置为 1,层级越高的动画被触发时,就最先被执行,默认 的层级都为零。在这里意味着只要跳跃动画被触发,它将优先与其他的动画被执 行。 anim ation["Jump"].layer = 1; //初始动画状态为静止。 anim ation.Stop(); } function Update () { //这段代码的意思是,竖直方向的方向键被按下,就播放 Go 动画,否则就还原 成站立动画 if (Mathf.Abs(Input.GetAxis("Vertical")) > 0.1) animation.CrossF ade("Go"); else animation.CrossF ade("idle"); //当空格键被按下就执行跳跃动画(*注:由于跳跃动画的层级比其他动画要高, 所以当同时按下方向键和空格键的时候,软件会最先播放跳跃动作) if (Input.GetKeyDown ("space")) animation.CrossF ade("Jump"); } 代码输入完毕之后,点击保存 ,并将该代码拖拽给舞台中的 “moveTest”模型。 然后点击测试按钮 ,测试一下效果。如图所示: 用键盘的方向键和空格键盘来控制人物,可以看到我们的人物在里面 行走自如,弹跳轻松。是多么的活灵活现啊! 二十一、粒子系统【Particle System】。 粒子系统顾名思义就是由一个一个很小的粒子构成,并带有一定 的物理属性。它可以被广泛的运用在火焰喷射效果,车辆经过沙漠溅 起尘埃等效果的实现。下面我们点选菜单栏中的“GameObject”—— >“Create Other” ——>“Particle System”向舞台添加一个粒子系统, 然后我们就可以在舞台上看见一个由无数个小点组成粒子球体,且它 们之间不断的相互运动着,效果如下图所示: 这时,请您确保粒子系统在被选中的状态下,在它的属性面板中修改 “Ellipsoid Particle Emitter”卷展栏下的“Max Size”【粒子最大尺寸】 为 0.5(默认与粒子最小尺寸“Min Size”是一致的,都为 0.1),“Max Energy”【最大生命周期】为 6(默认与最小生命周期“Min Energy” 是一致的,都为 3),这样粒子在产生的过程中将会是 0.1 到 0.5 之间 随机大小的颗粒,存在的生命周期将会是一个 3 到 6 的随机数字。并 在“Particle Anim ator”卷展栏中找到“Force”【力量】,将其中的 Y 值改为 5,为例子在 Y 方向增加一个 5 的力量,使它有种向上飘舞的 感觉。最终的效果如图所示: 有关粒子系统所有有关的参数,如下图所示: Ellipsoid Particle Emitter(椭圆发射器) Emit 勾选即启动 Min Size 粒子最小尺寸 Max Size 粒子最大尺寸 Min Energy 最小生命周期 Max Energy 最大生命周期 Min Emission 最小发射量 Max Emission 最大发射量 World Velocity 世界坐标系发射速度 Local Velocity 自身坐标系发射速度 Rnd Velocity 随机发射速度 Emitter Velocity Scale 发射器缩放值 Tangent Velocity 正切线发射速度(当只设置一个轴时, 发射范围会沿一个轴平面切齐) Simulate in World Space 勾选则会在世界坐标空间中模拟 One Shot 一秒只发射一次 Ellipsoid 椭圆面大小 Min Emitter Range 发射器的最小范围 Particle Animator(粒子动画) Does Animate Color 是否启动颜色动画 Color Animation 颜色变化选择 World Rotation Axis 让粒子以世界坐标系的 XYZ 方向旋转 Local Rotation Axis 让粒子以自身坐标系的 XYZ 方向旋转 Size Grow 让粒子以设定的比例随机变大或增加 Rnd Force 随机在每帧增加一个力看起来更生动。 数字越高,随机变化的程度也就越高。 Force 为粒子增加一个固定的施力方向。数字 越大,粒子所受到的力度也就越大。 Damping 粒子在运动过程中的衰减值。默认为 1, 为无衰减状态,小于 1 之后便开始产生 衰减。 Autodestruce 勾选之后。粒子系统所有的粒子在消失 之后,承载它的 GameObject 对象也跟 着消失。 Particle Render(粒子动画) Cast Shadows 是否产生阴影 Receive Shadows 是否接受阴影 Materials 粒子外观的材质 Camera Velocity Scale 改变这栏的数字,将会使得粒子在摄像 机前的渲染效果有所不同。 Stretch Particles 拉伸粒子,以达到镜头想要得到的效 果。 Billboard 当粒子面对镜头时才呈现 Stretched 朝粒子运动的方向去做拉伸延展 Sorted Billboard 当使用混合材质时,粒子会依照距离镜 头的远近做排列 Vertical Billboard 所有粒子沿着竖直方向上拉伸 HorizontalBillboard 所有粒子沿着水平方向上拉伸 Length Scale 粒子被拉伸的程度,必须在 Stretch Particles 中使用了拉伸效果才能起到作 用。 UV Animation 使粒子产生 UV 动画效果 X Tile 沿着 X 轴,每帧产生一次位移 Y Tile 沿着 Y 轴,每帧产生一次位移 Cycles 多久循环一次 (注:粒子说明文稿,由微澜虚拟(VRLAND)特别提供支持。) 二十二、“V isual Studio”结合,高效开发 Hummer 小游戏 第一步:新建一个名为“Hummer”的文件夹,并打开 U3D 制作软件。 在 U3D 中新建一个项目,并把刚才建立的“Hummer”作为项目文件 夹来使用。 第二步:为了便于管理,我们在新建项目的 Project【项目文件栏】中 点击鼠标右键——>“Create”——>“Folder”新建六个文件夹,并 分别命名为“Animation”、“Audio”、“Materials”、“Prefab”“Script”、 “Stage”用来存放不同用途的文件。 第三步:Ctrl+S 保存当前场景到“Stage”文件夹中,并取名叫做“Logo”。 在菜单栏中找到“Edit”——>“Preferences…”,在弹出的“Unity Preferences”对话框中找到“External Script Editor ”并将它后面的下 拉框选中为“Browse…” 浏览到我们“Visual Studio”可执行文件存 放的地方。这里我们将代码编辑器改成“Visual S tudio”以便利用它 和 C#高效的协同开发游戏。然后我们右键点击 Project【项目文件栏】 中的“Script”文件夹——>“Create”——>“C Sharp Script”新建一 个 C#脚本,并将它更名为“Logo”。这时候如果您将它拖到舞台的上 的任意对象上,系统报错 。还记得我前面所学 到的面向对象的编程语言吧?C#作为此类语言的一种,严格遵守类 名必须与文件名相同的规则。所以这时候我们必须打开“Logo.cs” 这个文件修改其类名为“Logo”才行。具体步骤:在 Project【项目 文件栏】中的“Script”文件夹下找到我们刚才新建的“Logo”脚本 文件并双击打开它。稍等片刻之后可以看到“Logo”脚本已经被“Visual Studio”所打开,并且我们的“Visual S tudio”自动为 U3D 创建了一 套项目文件。如图所示: 大家会在打开的“Logo”脚本中发现自动添加了“Start”和“Update” 两个代码段这是 U3D 为了方便开发者而做的模块。我们首先将现在 的类名改为“Logo”让它同文件名一致, 紧接着在“Visual S tudio”软件中点击“文件”——>“导出模版”, 在弹出的对话框中选择“项模版”,然后点击下一步: 紧接着选中您要导出的模版文件“Logo.cs”然后点击下一步: 在下面的这个面板中,不选任何的东西,直接点击下一步: 在下面这个窗口中写上模版的名字“Unity3DScript”和模版的说明文 字“U3d 脚本专用模版”,然后点击“完成”: 这时我们就已经将这套程序作为一个模版保存进了“Visual S tudio” 里面,如果您下一次还要在新建一个 C#脚本的时候,就不必在 U3D 中去建立了,直接在“Visual S tudio”即可。例如下面我们新建一个 “Player”的脚本,在“Visual Studio”的“解决方案资源管理器”中 右键点击“Script”文件夹——>“添加”——>“新建项”,在弹出的 对话框中找到我们刚才新建的模版“Unity3DScript”,然后输入新建 的脚本名字“Player”,然后点击添加。如下图所示: 这时我们会惊奇的发现,在“Visual S tudio”中新添加的脚本连类名 都不需要你改了,实在是很方便,如下所示: 二十三、利用内置动画系统来制作游戏的开场画面。 在几乎所有的游戏中,开始运行的时候总会显示一些关于游戏制 作者、游戏公司的 Logo 出现。在 U3D 中,大家可以利用它自身的内 置动画系统来轻松解决这个事情,下面我接着上一节的内容就来教授 大家如何来制作。 第一步:将您需要显示的 Logo 图片放入项目文件夹的“Assets”文 件夹内的“Materials”里面。 第二步:在“Logo”场景中,选中默认摄像机“Main Camera”,在它 的属性面板中将“Projection ”由原来的“Perspective ”改为 “Orthographic”这样可以使得摄像机的视野由棱锥变为长方形,不 再有视觉错差的感觉,观看的景象就像是一个 2D 画面。如图所示: 并接着在属性栏中把摄像机的背景颜色“Background”改为黑色 第三步:点击菜单栏中“GameObject”——>“Create Other ”——> “Plane”创建一个平面,然后用旋转工具调整它的正面面向摄像机。 这时候大家可以试着用移动调整工具 来拉近平面和镜头之间的 距离,发现平面并没有因为离摄像机近了而改变自己的显示大小,正 如我之前所说的,在摄像机的“Orthographic”模式下,一切显示物 体都已经变为 2D 的成像效果了。为了能显示出一个饱满的 Logo 图 像,我们利用缩放工具 将平面拉伸到和屏幕一样的大小。然后再 将事先准备好在 Project【项目文件栏】中的 Logo 图片拖放给这个平 面。如图所示: 但这时我们会发现 Game【动画面板】中的图像似乎显得非常暗淡, 这时可能您也许会想到添加灯光以照明图像。这是一个聪明的做法, 但为了保证我们的图像显示的明暗度能达到 100%的均匀,请您点击 菜单栏中“Edit”——>“Render Settings”,然后到“渲染设定”的属 性栏中找到“Ambient Light ”来调节它的环境灯光。 即可增加亮度。 第四步:确保平面对象“Plane”在选中的情况下,到它的属性面板 中找到材质卷展栏,点击它的色彩调节按钮“Main Color”,如下图红 框标出来的部分。 ,然在弹出的 “Color”【色彩调节面板】中,大家可以在最下面发现 R、G、B、A 四个调节框,分别代表物体的红色、绿色、蓝色、不透明的调节。但 这个时候我们去拨动不透明度的滑块,或则试图改变不透明的数值时 ,会发现对物体对象的显示毫无作用。这是由 于默认的材质模式不支持 alpha 通道的缘故,只要我们在材质卷展栏 中,将“Shader”后面的下拉选项选作为“Transparent”——>“Diffuse” 就可调节透明度了。 第五步:在任意一个面板上点击这个按钮 ——>“Add Tab”——> “Animation”添加一个动画面板,如下图所示: 然后在 Hierarchy【层次清单栏】中选中我们的平面对象“Plane”,到 Animation【动画面板】中点击录制按钮 ,给平面对象“Plane”添 加一个动画,并在弹出的存储窗口中将该动画取名为“Logo”并存储 在我们建立的“Animation”文件夹中。在动画面板中,我可以看到 平面对象的“Plane”的位置、旋转角度、尺寸等等都可以用来做动 画。如图中的列表: 这里我们只做平面的透明度动画,所以请在 Animation【动画面板】 中将材质球“Logo 1(Material)” 展开,并在其中找 到“Color.a”在最上面点击增加关键帧的按钮 ,然后将“Color.a” 后面的数值改成 0,让 Logo 在场景刚刚出现的时候不显示。紧接着, 我们将时间轴移动到 2 秒的这个位置 ,再点击 增加关键帧的按钮 ,然后将“Color.a”后面的数值改成 1,让 Logo 在场景中慢慢的渐变显示出来。紧接着按住 Ctrl 键不放,滑动鼠标滚 轮,以增加时间时间轴的显示长度,然后将时间轴移动到 3 秒的这个 位置 ,再点击增加关键帧的按钮 ,不做任何设 置,让 Logo 在画面中静止 1 秒中的时间。紧接着将时间轴移动到 5 秒的这个位置,再点击增加关键帧的按钮 ,然后将“Color.a”后面 的数值改成 0,让 Logo 在场景中慢慢的淡出画面。 第六步:双击“Script”文件夹下面的“Logo”脚本,然后在 VS(下 面的文章用 VS 来指代 Visual Studio)中将“Logo”脚本改成如下的 代码段: using UnityEngine; using System.Collections; public class Logo : MonoBehaviour { void startGame() { Application.LoadLevel(1); } } 并点击保存。由于 startGame()并不是 U3D 中内置的函数,所以在没 有事件对它进行触发的时候,它是不被运行的。接着将这段代码拖放 给我们的平面对象“Plane”。 第七步:回到 Animation【动画面板】中,确保平面对象“Plane”在 选中的情况下,在动画剪辑选择框中选择我们之前创建的“Logo”动 画,如图所示: 然后点击录制按钮 ,重新激活该动画剪辑编辑状态,让后将时间 滑块拖动到动画结束的那一帧,并双击时间刻度线下面的那一个横栏 这时候会弹出一个“Edit Animation Event”【动画事件编辑器】,请将 “Function Name: ”后面的下拉框选择为我们的场景切换函数 “startGame()”,如图所示: 编辑完成之后,Ctrl+S 保存我们的动画。 第八步:点击运行按钮,运行一下游戏看看。当 Logo 最后消失的时 候,控制面板报错: 这是由于我们的下一个场景还没有创建,所以动画事件 startGame() 无法加载一个不存在的场景。所以我们得 Ctrl+N 创建一个新的场景, 并 Ctrl+S 保存该场景名为“start”,将它存储在“Stage”文件夹的下 面。紧接着点选菜单栏中的“File”——>“Build Settings… ”,在弹 出框中将我们的两个场景“Logo”和“Start”先后拖放入“Scenes In Build”,并确保它们后面的序号“Logo”为 0、“Start”为 1,这直接 决定了它们的加载顺序,startGame 中的加载代码 Application.LoadLevel(1) 就是指加载后面序号为 1 的场景,如图所示: 重新点击运行按钮看看,当 Logo 播放结束,顺利的加载了场景“start” 二十四、利用代码绘制 GUI 背景图片和 GUI 按钮 第一步:接着上一节的内容,我们双击“Stage”文件夹下的“start” 场景文件,来到“start”场景中。 第二步:创建一个游戏开始时需要展现的图片“humen.jpg”,并保存 到“Materials”文件夹中。 第三步:双击“Script”文件夹下的任意一个 C#脚本来启动 VS 软件。 在 VS 的编程环境中,鼠标右键点击“Script”文件夹——>“添加” ——>“新建项”,新建一个名为“startGame.cs”的脚本,然后输入 代码: using UnityEngine; using System.Collections; public class startGame : MonoBehaviour { //创建一个材质对象“backGround”,主要用作感应背景图片的接口 public Texture backGround; void OnGUI(){ //绘制一个背景图片,坐标X等于、Y等于、宽度等于场景的宽度、高度等于场景的高度,绘制的 对象是backGround所感应进来的材质图片 GUI.DrawTexture(new Rect(0, 0, Screen.width, Screen.height), backGround); } } 然后将这段代码拖放给摄像机对象“Main Camera ”,并在 Hierarchy 【层次清单栏】点选“Main Camera”,到它的属性面板中找到刚才添 加的“startGame(Script)”卷 展 栏 ,将 图 片“ humen.jpg”拖放到“Back Ground”后面的感应接口上,如图所示: 第四步:Ctrl+N 创建一个新的场景,并 Ctrl+S 保存该场景名为 “gameScreen”,将它存储在“Stage”文件夹的下面,用它来做为游 戏的运行场景。紧接着点选菜单栏中的“File”——>“Build Set- tings…”,在弹出框中将我们新建的场景“gameScreen”拖放入“Scenes In Build”。 然后双击“Script”文件夹下的“startGame”C#脚本,在其中添加一 段跳转到“gameScreen”场景的按钮代码,如下面红框框出来的部分: using UnityEngine; using System.Collections; public class startGame : MonoBehaviour { //创建一个材质对象“backGround”,主要用作感应背景图片的接口 public Texture backGround; void OnGUI(){ //绘制一个背景图片,坐标X等于、Y等于、宽度等于场景的宽度、高度等于场景的高度,绘制的 对象是backGround所感应进来的材质图片 GUI.DrawTexture(new Rect(0, 0, Screen.width, Screen.height), backGround); //绘制一个跳转到“gameScreen”场景的按钮 if (GUI.Button(new Rect(Screen.width/2 - 100f, Screen.height/2 - 30f, 200f, 60f), "Start Game")) Application.LoadLevel(2); } } 紧接着双击“Stage”文件夹下的“start”场景文件,回到“start”场 景中,点击一下测试按钮 ,可以看到如下效果: 然后点击“Start G ame”按钮,就可以跳转到我们新建的场景 “gameScreen”中(注:在“start”场景中的画面,完全由 GUI 代码 绘制而成,所以在您未对项目运行的时候,Game【动画面板】中将 不会显示任何东西。)。当然,如果您对现在的字体样式和字体颜色不 满意的话,我们只需要为它附加一个 GUISkin,既可以改变它的样式。 改变后的按钮代码如下: using UnityEngine; using System.Collections; public class startGame : MonoBehaviour { //创建一个材质对象“backGround”,主要用作感应背景图片的接口 public Texture backGround; //创建一个GUI皮肤对象“customSkin”,主要用作感应外部GUI的接口 public GUISkin customSkin; void OnGUI(){ //绘制一个背景图片,坐标X等于、Y等于、宽度等于场景的宽度、高度等于场景的高度,绘制的 对象是backGround所感应进来的材质图片 GUI.DrawTexture(new Rect(0, 0, Screen.width, Screen.height), backGround); //设置GUI的皮肤 GUI.skin = customSkin; //绘制一个跳转到“gameScreen”场景的按钮 if (GUI.Button(new Rect(Screen.width / 2 - 100f, Screen.height / 2 - 30f, 200f, 60f), "Start Game")) Application.LoadLevel(2); } } 紧接着点选菜单栏中的 “Assets”— — >“Create” ——>“GUI Skin” 创建一个皮肤组件,然后点选这个新创建的皮肤组件,在它的属性面 板中找到“Button”这一项,然后将它里面的字体颜色设置为黄色、 字体大小为 20、字体样式为加粗,如图中框选出来的部分: 紧接着选中摄像机对象“Main Camera”到它的属性面板的“startGame (Script)”卷展栏下找到新添加的接口“Custom Skin”,然后将将我 们新创建的皮肤组件拖放给这个接口,如图所示: 然后我们重新运行一下“start”场景,可以看到按钮的颜色和字体已 经改变了,如下图所示: 二十五、 创建一个不断重复播放的 2D 背景 第一步:双击“Stage”文件夹下的“gameScreen”场景文件,来到 “gameScreen”场景中。点选默认摄像机“Main Camera”,在它的属 性面板中将“Projection ”后面的下拉框改为“Orthographic ” 的 2D 显像模式。 第二步:创建一个平面,并旋转这个平面的正面面向摄像机,并缩放 这个平面的宽度为舞台宽度,高度为舞台高度的两倍(注:这里之所 以要设置高度为舞台高度的两倍,是因为这样方便做向下运动的循环 动画。),位置为:0,0,0,然后拖放一个长宽比例与之相同的沙土 贴图给这个平面。如下所示: 第三步:这时的场景颜色显得过于暗淡,为了增强场景亮度,我们点 选菜单栏中“GameObject”——>“Create Other” ——>“Directional Light”来添加一个定向光源作为阳光。添加后的太阳光入射角度与 我们的平面正好垂直,光照为最充足的状态。如果您发现场景中依然 没有什么关照,那请您自行调整“Directional light”的光照角度。添 加阳光后的场景亮度对比: 第四步:为平面添加一段运动代码,让平面从上至下的不断循环滚动。 来到 VS 环境下面,鼠标右键点击“Script”文件夹——>“添加”— —>“新建项”,新建一个“rollBg.cs”的脚本,具体代码如下: using UnityEngine; using System.Collections; public class rollBg : MonoBehaviour { //定义地平面移动的初始速度 public static float bgSpeed = 100; void Update() { transform.Translate(Vector3.down * Time.deltaTime * bgSpeed,Space.World); //如果地平面移动到舞台的最下方,就让它重新回到舞台的最上方,不段的反复滚动。 if (transform.position.y < -105) transform.position = new Vector3(transform.position.x, 110f, transform.position.z); } } 写完之后,将这段代码拖放给地平面对象“Plane”。 二十六、用代码控制石头随机掉落的位置、形状、和旋转角度, 并用“Horizontal”来控制汽车的运动。 第一步:利用 3D Max 创建一个迎面而来的石头模型。如下图所示: 建好之后,将它导出到“Prefab”文件夹内,并命名为“stone.fbx”。 接着再利用 3D Max 创建一个 Hummer 汽车的模型。如下图所示: 由于我们只是从车顶观看整个模型,所以在材质和模型细节方面可以 不用过多的去在意。建好之后,将它导出到“Prefab”文件夹内,并 命名为“hummer.fbx”。 第二步:将石头模型“stone”拖放到舞台可视范围的最上方,将汽车 模型“hummer”拖放到舞台可视范围的最下方。 但这时候的模型似乎显得过于渺小,请分别点击 Project【项目文件栏】 中的源模型文件“stone”和“hummer”,并在他们“FBXImporter” 卷展栏下,将 Scale Factor 数值调节到你认为可以的模型大小数值 (注:在调节过程中,你不会立刻 看到模型的大小变化,请在属性面板的最下面点击“Apply”按钮 )。然后接着旋转汽车的模型顶部面向我们的摄像机。最后在 Game【动画面板】观看到的最终效果如图所示: 第三步:来到 VS 的编程环境中,鼠标右键点击“Script”文件夹— —>“添加”——>“新建项”,为石头添加一个运动控制脚本 “enemyStone.cs”,具体的代码如下: using UnityEngine; using System.Collections; public class enemyStone : MonoBehaviour { //初始化石头的运动速度 public static float moveSpeed=100f; //初始化石头的活动范围为舞台的宽度范围 private float EmaxWidth = 140f; private float EminWidth = -140f; private float EresetPosition; //初始化石头的角度旋转范围 private float EmaxRotate = 180; private float EminRotate = -180; private float EresetRotate; //初始化石头的大小变化范围 private float EmaxScale = 1.3f; private float EminScale = 0.9f; private float EnewScale; void Start() { //游戏刚开始运行的时候,让石头复位 transform.position = new Vector3(0f, 105f, 0f); } // Update is called once per frame void Update() { //在石头的最大和最小活动范围内,读取一个随机值 EresetPosition = Random.Range(EmaxWidth, EminWidth); //在石头的最大旋转角度和最小旋转角度范围内,读取一个随机值 EresetRotate = Random.Range(EmaxRotate, EminRotate); //在石头的最大缩放值和最小缩放值之间,读取一个随机值 EnewScale = Random.Range(EmaxScale, EminScale); //设置石头向下移动,并且坐标参考是“Space.World”世界坐标 transform.Translate(Vector3.down * moveSpeed * Time.deltaTime,Space.World); //如果石头的坐标值低于舞台可视范围的最低坐标值,就让石头复位,且变换一下石头的位置、 角度和大小 if (transform.position.y < -105f) { transform.position = new Vector3(EresetPosition, 105f, transform.position.z); transform.Rotate(new Vector3(EresetRotate, EresetRotate, EresetRotate)); transform.localScale = new Vector3(EnewScale, EnewScale, EnewScale); } } } 保存脚本之后,回到 U3D 环境并将该代码拖放给舞台上的“stone”, 然后点击运行一下游戏。大家会看到石头“落”到舞台的下方之后, 又从上方继续的掉落下来,但从新掉落的石头形状、大小、和位置已 经不再相同。如图所示: 第四步:点击菜单栏中的“Edit” ——> “Project Settings ”——> “Input”,然后在属性面板中点开“Axes”卷展栏,大家可以在这里 看到系统已经为我们内置了一些控制对象动画和运动的按钮,再进一 步打开“Horizontal”卷展栏,我们可以看到这是一个专为控制物体 在水平轴线方向上运动的内置按钮,且默认的是用“←”键 和“→”键 来控制,或是用“A”键 和“D”键 来控制。且默认的运动轴线是 X 轴 。 第五步:直接双击“Script”文件夹下的“Player”脚本(注:这个脚 本是我们之前就已经创建好了的),然后输入汽车的控制脚本,具体 代码如下所示: using UnityEngine; using System.Collections; using UnityEngine; using System.Collections; public class Player : MonoBehaviour { //初始化汽车的运动速度 public static float PlayerSpeed = 50; void Update() { //设置汽车随着键盘的上的“A”和“D”,或者是“←”和“→”键按下来移动 float hummerMove = Input.GetAxis("Horizontal") * PlayerSpeed * Time.deltaTime; transform.Translate(Vector3.left * hummerMove); //如果汽车超过舞台的显示范围,则设置它从另外的一边出现 if (transform.position.x < -140f) transform.position = new Vector3(140f,transform.position.y,transform.position.z); if (transform.position.x > 140f) transform.position = new Vector3(-140f, transform.position.y, transform.position.z); } } 二十七、创建相撞时的爆炸效果,和碰撞测试代码 第一步:点击菜单栏“GameObject”——>“Create Other ” ——> “Particla System ”添加一个粒子系统,并调节粒子系统的属性参数 如下,使它呈现一个爆炸的扩散状态。具体参数:Min Size:10(粒子 的最小尺寸为 10),Max Size:15(粒子的最大尺寸为 15),Min Energy 0.5(粒子的最小生命周期为 0.5),Max Energy 1(粒子的最小生命周 期为 1)将这个周期调短是由于爆炸之后出现的火光很短,调短之后 可以使得画面看上去更有张力。Min Emission 80(最小发射量为 80), Max Emission 100(最大发射量为 100),Tangent Velocity 下的 X 和 Z 为 30,代表粒子爆炸向四周散发的半径为 30。将“One Shot ”复选 框勾上,让粒子呈现出从中心向外炸开的效果。如图所示: 然后再到“Particle Animator”卷展栏下调节颜色,使得粒子更像火焰。 并将“Autodestruct”复选框打上勾,使得爆炸效果只进行一次。 第二步:在菜单栏中点击“Assets”——>“Create” ——>“Prefab”, 创建一个预置对象并取名叫做“Boom”,将我们刚创建的粒子系统和 爆炸的声音文件都拖放给它。 然后将 Hierarchy【层次清单栏】中的“Particle System”删除。 第三步:双击“Script”下的“Player”脚本,为汽车添加碰撞爆炸脚 本,具体代码如下面框出来的代码部分: using UnityEngine; using System.Collections; public class Player : MonoBehaviour { public static float PlayerSpeed = 50; //初始一个游戏对象“boom”,用它来感应爆炸的预置对象 public GameObject boom; void Update() { float hummerMove = Input.GetAxis("Horizontal") * PlayerSpeed * Time.deltaTime; transform.Translate(Vector3.left * hummerMove); if (transform.position.x < -140f) transform.position = new Vector3(140f,transform.position.y,transform.position.z); if (transform.position.x > 140f) transform.position = new Vector3(-140f, transform.position.y, transform.position.z); } //设定一个碰撞检测函数 void OnTriggerEnter(Collider otherObject) { //如果碰撞对象的标签叫做“stone”那么就Instantiate(初始化)一个爆炸对象,并让汽车对象 消除 if(otherObject.tag=="stone"){ Instantiate(boom, transform.position, transform.rotation); Destroy(gameObject); } } } 代码改写完毕,在 Hierarchy【层次清单栏】中选中“stone”,然后到 它的属性面板中找到 Tag 后面的下拉框,点选“Add T ag…”添加一 个名为“stone”的标签 。然 后重新在 Hierarchy【层次清单栏】中选中“stone”,在它的属性面板 中将 Tag 后面的下拉框改选为刚才添加进来的标签“stone” 。紧接着,我们分别点选汽车对象“Hummer” 和石头对象“stone”,在菜单栏中“Component”——>“Physics”— —>“Rigidbody”分别为汽车对象和石头对象添加一个刚体属性。然 后运行一下程序试试看。大家发现了什么?石头和汽车并未检测到任 何的碰撞,这究竟是什么原因呢?那是因为碰撞一定要有碰撞边沿才 能检测得到,而 U3D 中创建的物体自身就带有碰撞边沿,但从外部 加载进来的模型却是没有的。下图为 U3D 中添加内置物体对象,所 对应属性栏中内置的碰撞器: 立方体中的碰撞器。 球体中的碰撞器。 药丸对象中的碰撞器。 圆柱体中的碰撞器和药丸 对象的碰撞器是相同的 平面对象中的网格碰撞器 这一些碰撞器直接决定了该物体,将在什么范围内和其他具有碰撞器 的物体产生碰撞效应。那要怎样为我们外部导入的模型创建这一类的 碰撞器呢?其实非常简单,我们首先选中汽车模型,观察一下整个汽 车的边沿呈现出一个立方体的形状。然后点选菜单栏中的 “Component”——>“Physics”——>“Box Collider”,为汽车添加 一个立方体形状的碰撞器,如图所示: 如果您发现这个碰撞边沿并没有达到汽车边沿的形状大小,有一个很 简单的方法,可以让它与模型边沿迅速对齐。在模型的属性面板中, 找到添加进来的碰撞器“Box Collider”,然后点选它后面的设置按钮 ——>“Reset”,让系统自动重设一下就可以了。由于石头模型并 不是一个规则模型,所以关于添加不规则模型的碰撞器,我下面单独 列出一节来讲。 二十八、网格碰撞体的正确添加方式 第一步:在 Hierarchy【层次清单栏】中选中“stone”,然后点选菜单 栏中的“Component”——>“Physics”——>“Mesh Collider”为石 头添加一个网格碰撞器,但这时在 Scene【场景面板】中却看不到任 何的碰撞边线框,如图所示: 这是由于网络碰撞器是一个没有固定形状的碰撞器,不像其他的碰撞 器都有自己固定的形状。 第二步,在“stone”的属性面板中,找到刚才添加进来的“Mesh Collider”,将“Convex”复选框打上勾。使 U3D 自动为“stone”绘 制出碰撞边沿,如下图所示: 但大家要注意一下,这里的碰撞边沿,并不是按照不规则模型边沿 100%绘制的,而是一个粗略的边沿碰撞线,如下图中的模型网络碰 撞边: 全部设置完毕,点击运行按钮 来运行一下游戏,大家已经可以看 到碰撞效果了。 二十九、巧用枚举来设定游戏角色的状态 现在的游戏中,汽车被撞一次就永远的消失了,这很不符合普通 游戏的常识。在我们寻常的游戏当中,游戏主人翁往往会有一定的生 命值,在生命值没有消耗完之前,我们的主人翁是可以复活的,并有 一段的时间处于无敌状态。下面我就教大家如何巧用枚举来实现游戏 对象的无敌状态,与非无敌状态切换。首先双击“Script”文件夹下 的“Player”脚本,然后为汽车添加状态选择代码: using UnityEngine; using System.Collections; public class Player : MonoBehaviour { public static float PlayerSpeed = 50; public GameObject boom; //设定游戏角色的生命值 public int lifeNumber = 3; //设定游戏角色的两种状态 enum State { Playing, Revival } //设定游戏角色的初始状态 private State state = State.Playing; void Update() { //设置汽车随着键盘的上的“A”和“D”,或者是“←”和“→”键按下来移动 float hummerMove = Input.GetAxis("Horizontal") * PlayerSpeed * Time.deltaTime; transform.Translate(Vector3.left * hummerMove); //如果汽车超过舞台的显示范围,则设置它从另外的一边出现 if (transform.position.x < -140f) transform.position = new Vector3(140f,transform.position.y,transform.position.z); if (transform.position.x > 140f) transform.position = new Vector3(-140f, transform.position.y, transform.position.z); } void OnTriggerEnter(Collider otherObject) { //这里多添加一个角色状态的判断,如果游戏状态不是Playing,那么角色将不进行碰撞检测, 即无敌状态 if(otherObject.tag=="stone" && state == State.Playing){ //将游戏角色的状态设置为复活状态,即无敌状态 state = State.Revival; //由于碰撞函数里面不直接支持时间等待函数yield return new WaitForSeconds,所以要利 用StartCoroutine函数做一个调用 StartCoroutine(hitStone()); } } IEnumerator hitStone() { //只要生命值大于,就产生碰撞后的爆炸 if (lifeNumber > 1) { Instantiate(boom, this.transform.position, Quaternion.identity); Destroy(gameObject); lifeNumber--; //在游戏角色等待1秒后,恢复非无敌状态 yield return new WaitForSeconds(1); state = State.Playing } } } 但当您填写完这段代码,并运行它的时候,却发现汽车依然被撞击之 后,就不再出现。其实只要我们细心想想,在碰撞之后的检测代码中 有一个Destroy(gameObject)函数,已经将我们的汽车对象消除掉了, 而这段代码又是加载在汽车对象上面执行的,难怪看不到后面的效 果。所以我们不能再使用Destroy()函数,但我们又得让汽车确确 实实的消失,那么就不让角色对象进行渲染就好了 transform.renderer.enabled = false。等到2秒中之后,再让汽车又重新 在场景中渲染出来transform.renderer.enabled = true。但在整个复活的 过程中,画面上看不到任何角色对象,又显得太单调了些,所以我们 在复活的整个过程中再加上闪烁效果,相关代码如下所示: IEnumerator hitStone() { if (lifeNumber > 0) { Instantiate(boom, this.transform.position, Quaternion.identity); //这里改为隐藏对汽车的渲染,而不将汽车消除 transform.renderer.enabled = false; lifeNumber--; //汽车被撞以后每0.2秒闪烁一下,一共闪烁十下 int i = 0; while(i<10){ transform.renderer.enabled = !transform.renderer.enabled; if (transform.renderer.enabled == true) i++; yield return new WaitForSeconds(0.2f); } //在游戏角色等待1秒后,恢复非无敌状态 yield return new WaitForSeconds(1f); state = State.Playing; } } 三十、游戏结束场景的设置 第一步:Ctrl+N新创建一个场景,并Ctrl+S保存该场景并命名为 “gameOver”同样的将它保存到“Stage”文件夹下面。 第二步:打开VS编程环境,鼠标右键点击“Script”文件夹——>“添 加”——>“新建项”,为结束场景创建一个名为“gameOver”的脚 本,然后输入场景画面的绘制代码以及返回游戏和退出游戏的代码: using UnityEngine; using System.Collections; public class gameOver : MonoBehaviour { //初始化一个材质对象overBG,主要是作为感应背景图片的接口 public Texture overBG; void OnGUI(){ //绘制背景图片,大小和场景大小一样 GUI.DrawTexture(new Rect(0, 0, Screen.width, Screen.height), overBG); //设置返回游戏的按钮 if (GUI.Button(new Rect(10, Screen.height - 50, 100, 30), "ReStart Game!")) Application.LoadLevel(2); //设置退出游戏的按钮 if (GUI.Button(new Rect(Screen.width - 110, Screen.height - 50, 100, 30), "Quit")) Application.Quit(); } } 第三步:将代码保存之后,拖放给场景“gameOver”中的摄像机“Main Camera”,然后到摄像机的属性面板中,找到我们用代码设置的材质 接口“Over BG”,然后将背景图片拖放给它,如图所示: 第四步:将新创建的场景“gameOver”拖放到“Build Settings”列表 中,如图所示: 第五步:双击“Script”文件夹下的“Player”脚本文件,我们这里还 需要做一些设置,因为这时汽车在生命值消耗殆尽之后,没有做下一 步的指示,整个画面像死机了一样。所以我们还得在这段代码中做一 些修改,使得汽车在生命值消耗完了之后,跳转到游戏结束场景。 IEnumerator hitStone() { if (lifeNumber > 0) { Instantiate(boom, this.transform.position, Quaternion.identity); transform.renderer.enabled = false; lifeNumber--; int i = 0; while (i < 10) { transform.renderer.enabled = !transform.renderer.enabled; if (transform.renderer.enabled == true) i++; yield return new WaitForSeconds(0.2f); } yield return new WaitForSeconds(1f); state = State.Playing; } //生命值消耗完,跳转到结束场景 else Application.LoadLevel(3); } 本节小结: 这几节中,做的Hummer游戏都比较简单。但我已将带有加分, 通关加速等功能完整版Hummer小游戏制作出来了。需要源码的朋友, 可凭汇款小票与我联系。 你不能不看的结束语: 当今的中国已经有不少Unity3D的爱好者和开发者了,他们都被 U3D强大的成像功能和数据功能所吸引,在未来的2、3年内,U3D将 会成为最热门的软件之一。但在这个时候,请大家不妨想想,如果用 U3D来制作3D Web,浏览它的用户常常为了加载一个庞大的场景而 等上2、3个小时,试问有哪一个网页浏览者会选择这样做?所以也请 您在学习U3D的时候,不妨高瞻远瞩,看看只用几十KB就可以浏览 到一个格斗游戏的《第五章 统领未来的3D超级浏览器》,看看它的 架构,看看怎么来鉴证下一个比尔盖茨的诞生!
还剩130页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 10 金币 [ 分享pdf获得金币 ] 0 人已下载

下载pdf

pdf贡献者

liushije

贡献于2016-12-12

下载需要 10 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!
下载pdf