Unity3D for iOS初级教程:Part 3/3(上)
转自:http://www.cnblogs.com/alongu3d/archive/2013/06/01/3111738.html
欢迎来到第三部分,这是Unity 3D for iOS初级系列教程的最后一个部分!
在这个系列的第一部分,你参观了基本的Unity工具,创建了带有一个简单角色控制机制的游戏,并且学习了如何部署你的项目到iOS上。
然后在这个系列的第二部分,你增强了你英勇的小方块的移动,并且给这个世界带来一些生命,它拥有了天空,草地和一个起伏的地形。
在第三部分,也是最后一部分,你将要添加游戏玩法到项目中。替代简单的绕着场景乱转,你英勇的小方块需要在一个给定的时间里,冲刺穿过一个终点线。
要给你的角色一些挑战,在方块以z字路线通向终点的路上,障碍物会像雨点一样落向方块。一个倒计时的时钟添加到剧本中。成功会伴随欢呼 – 失败则是震耳欲聋的沉默.:]
你也几乎接近终点线了,所以记住 – 我行我素!(“Huey Lewis And The News”中的一首歌名)
开始吧:看到尽头了!
首先,保存Level_2场景作为一个新的场景,命名为Level_3. 你在这个教程的第三部分所做的所有修改都保存在这个新的场景中。
你会用两个圆柱和一条连接它们的粗线来创建一条终点线,这样玩家可以清楚的看见目标的方向。这个终点线包括一个不可见的墙,它被用来当你英勇的小方块穿过终点线的时候的触发器。
选择GameObjectCreate Empty来创建一个新的物件来代表终点线。这是一个父GameObject, 在它之下,你可以添加圆柱,线和一堵墙。
通过Inspector面板,将这个物件重命名为Finish Line,或者右击这个物件,然后选择Rename. 设置Transform Position到0,0,0.
要
创建第一个圆柱,选择GameObjectCreate OtherCylinder。重命名它为Post1.设置Transform
Scale为1,3,1. 设置Transform
Position为-10,0,20,把它放在玩家的前面靠左边。用Move工具,调整y位置,让圆柱型物件的底部比地面略微高一些。
提示:从z轴视角观察场景会帮助你方便的做这样的调整。

拖动Post1 GameObject,然后把它放到Finish Line GameObject下面,设置后者作为Post1的父对象。
要创建第二个圆柱,选中Post1,右击然后选择Copy. 再次右击然后选择Paste. 从Post1到Post2重命名新的GameObject. 使用Move工具调整新坐标,让这个圆柱到玩家的右侧。
提示:从y轴观察场景(从上面),会对你的调整有帮助。另一个可选择的方式是,设置Transform x position到10,也应该达到这个目的。

下一步,创建墙来帮助你监测当终点线被穿过的时候。选择GameObjectCreate OtherCube,然后重命名它为Goal.设置
Transform Scale为24,10, 0.5.设置初始的Transform Position为0,2,0
移动这堵墙到两个圆柱后面,如果你需要,调整x缩放的值来让这堵墙从一个圆柱扩展到另一个圆柱。
让这堵墙仍然被选中,打开InspectorBox Collider组件,然后勾选Is Trigger的值。不要勾选Mesh Renderer component让这堵墙不可见。
拖动Goal GameObject,然后把它放置在Finish Line GameObject的下面,让Finish Line GameObject作为父物件。
连点成线
下一步,你会创建一条连接圆柱的线,让玩家可以清楚的看见终点线。你将要通过脚本从一个圆柱到另一个圆柱画一条线来完成这个动作。
选择AssetCreateJavaScript来创建一个新的脚本,然后命名它为FinishLineRender.在项目视图里通过双击打开这个脚本。删除自动生成的函数,然后添加下面的代码:
// The finish line posts |
LineRenderer类让你在3D空间画一条线。给出点的阵列,你可以使用Line Renderer组件(ComponentsEffectsLine Renderer)来画直线。
你也可以添加Line Renderer到Finish Line对象下,然后为Post1和Post2硬编码坐标位置,但是通过代码创建一个Line Renderer是相当容易的。就像你这里做的。
你在Start()函数里画了这根线,因为你仅仅需要发生一次。首先你添加LineRenderer脚本界面组件,然后你设置这条线的第一个和第二个点到捆绑到两个圆柱的输入变量的值。你设置renderer的材质。
最后你设置从起始点到结束点线的颜色。这个color变量是公共的,所以你可以改变它。
关联这个FinishLineRender脚本组件到Finish Line GameObject上。
提示:你可以通过选择Finish Line物件,然后在Inspector点击Add Compoment来添加这个脚本。这会弹出一个搜索框 – 简单的输入“FinishLineRender”单词的前面几个字母,然后它会显示你要的脚本。

分别分配Post1和Post2 GameObject到Post 1和Post 2变量上。
在Unity编辑器中预览这个游戏。你应该看见两个目标圆柱和一条绿线穿过它们代表终点线。停止游戏。
下一步,你将会创建一个用来探测终点线被穿越事件的新的脚本,然后会关联这个新的脚本到Goal GameObject上。要完成这个步骤,选择AssetsCreateJavaScript,然后命名这个脚本为FinishLineDetection.
打开这个新的脚本,然后删除自动生成的函数。添加下面的代码:
function OnTriggerEnter(other : Collider) {
|
你调用OnTriggerEnter()函数,当其他碰撞物进入这个GameObject. 这个游戏对象需要被设置为针对这个事件激活的触发器(你已经为这个Goal物件这样做了)。
角色GameObject有一个Character Controller组件,带有一个碰撞器。所以当玩家跑进Goal GameObject后,OnTriggerEnter()事件会被触发。
在你的代码里,你检查如果进入Goal的GameObject有一个标签命名为”Player”。如果属于这种情况,这个英勇的小方块已经穿过了终点线。
关联这个FinishLineDetection脚本到Goal GameObject上。
提示:在Hierarchy视图中,选中Goal物件,你可以从项目视图中拖动FinishLineDetection脚本到InspectorAdd Component按钮来关联这个脚本到GameObject上。
在你标记这个角色之前,给了这个角色GameObject一个普通,老套的“方块”名字。要保持事情的一致性,重命名这个方块GameObject到Player.
现在,添加一个标签到这个角色物件上,让它可以完成终点线的监测逻辑。在玩家的Inspector中,下拉Tag选择器,然后选择Player.

Player是预先构建的可用的标签之一。以后,你也可以创建你自己的标签来帮助识别游戏中的所有其他的敌人。
点击Play并移动英勇的小方块穿过目标线。你应该看见“You made it!!!”这条日志信息,让你知道你的角色穿过了终点线。
是的,英勇的小方块可以到达目标线,并且赢得这个游戏,但是你不能让它太容易了。你应该提高两级的复杂性到这个游戏里:一个基于时间的挑战和障碍物。首先让我们添加障碍物。
创建发射器
创建一个空的GameObject,然后把它添加到场景中。命名它为Launcher. 这个代表来自邪恶阻挡帝国的发射器发射一些障碍物来阻止英勇的小方块前进。
使用Move工具,在角色和终点线的z轴方向之间放置一个launcher对象,高于玩家。你可以设置transform位置为0,12,8作为起始位置,如果有必要可以微调。
发射器存在的主要作用是发射障碍物,所以你需要给它一些可以发射的东东。
在Unity中通常创建弹药的方式是,通过设计一个GameObject,然后转换为一个可以在场景中实例化的预制件。你将要创建一个障碍物GameObject,将它转变为预制件,然后让Launcher负责发射障碍物到倒霉的角色上。
创建障碍物
创建一个方块GameObject,然后命名它为Obstacle. 设置Transform Scale为2,2,2,因此它要比玩家大一些并且更加吓人一些。这些方块走向了邪恶的一边。:]
给
障碍物一个有趣的外观以区别于默认的灰色。要与示例比配,首先从Character Controller包导入一个材质:选择AssetsImport
PackageCharacter
Controller,然后选择constructor_done材质和下图显示的相关的纹理,最后点击Import
新的材质应该出现在你的项目视图中。
选择Obstacle GameObject.通过修改InspectorMesh RendererMaterialsElement 0属性来改变渲染的材料。点击这个属性边上的原点,会弹出 Select Material对话框。
选择你刚才导入的constructor_done材质。关闭Select Material对话框。
现在你必须标注Obstacle GameObject,这样后面当一个新的游戏开始的时候你可以清除场景中的Obstacle实例。
为了这个目的,创建一个新的标签名叫Enemy. 点击InspectorTagAdd Tag. 标签管理器会出现在面板的右侧。通过点击Tags标签边上的三角展开标签数组。修改Element 0的值从0到Enemy。
选择Obstacle GameObject,然后用新的Enemy标签来标记这个物件。
当Obstacle被实例化的时候,你将要添加的代码希望有一个关联到障碍物上的是一个刚体组件。通过添加一个刚体来完成这步。选择ComponentPhysicsRigidbody(Obstacle仍然被选中):
在项目视图中点击Asset文件夹。通过选择AssetsCreatePrefab创建一个预制件。项目视图显示一个空的预制件。命名它为Obstacle.
注意:如果你有比上面截屏更大的资源图标,并且想知道如何得到资源项的列表视图,简单的方式是向左滑动滑块下面的资源列表.:]
拖动Obstacle GameObject到新的预制件上。
预制件改成了蓝颜色来指示他已经被赋值。
现在你已经创建了这个预制件作为可以复用的资源。在场景中你不再需要它。launcher会接管实例化Obstacle实例的任务,当需要的时候。在Hierarchy视图中,选择Obstacle GameObject, 右击然后选择Delete.
释放海怪…错误,障碍
下一步,通过脚本创建逻辑来完成发射障碍物来这个过程。
创建一个新的脚本资源,然后命名它为ObstacleLauncher.
提示:你可以在项目视图中点击右键,然后选择CreateJavaScript来创建一个脚本。
打开这个新的脚本,然后用下面的代码替换自动生成的函数:
var projectile : Rigidbody; |
这个发射器被编程,用来在角色的前面发射一定数量的障碍物。它因此需要一个代表角色的输入,当分配GameObject到脚本的时候,你可以使用编辑器通过拖动GameObject到脚本的变量上来完成这步。Start()函数代码展示了完成这步的另一种方式。
在Start()中,一个看看那里是否没有目标被赋值的检查。如果没有目标被找到,代码查询一个带有Player标签的GameObject,然后把这个GameObject赋值到目标变量上。
GameObject.FindGameObjectWithTag()
函数调用是典型的花开销的调用,因为你需要遍历所有的GameObject.所以你应该想在Start()中调用(它只会被调用一次),而避免把它放到,
也就是说,Update()中(它会被调用多次)。
在代码中, Update()首先检查发射器是否已经发射允许发射的最大数量的障碍物。如果不是,它也要检查一个设置的时间间隔是否过了。这步是用来避免在一个较短的时间内发射太多的障碍物。
如果是时候发射另一个障碍物了,那么Obstacle预制件根据发射器的位置和旋转角度被实例化。这个实例化的障碍物然后被已锁定角色前进的方向发射,因此刚好落在角色的前面。
现
在保存代码,然后舒展一下筋骨。首先,关联这个ObstacleLauncher脚本到Launcher GameObject.
分配Obstacle预制件到脚本的projectile变量上(你可以从资源列表中拖动预制件到变量上)。分配Player
GameObject到脚本的target变量上.
在Unity编辑器中试玩这个游戏,并且检查当英勇的小方块移动的时候在它前面有被发射的障碍物。调整发射器的位置,这样可以让被发射的障碍物在玩家和终点线之间。你也可以通过在z轴远离玩家的方向,移动Finish Line GameObject来做出一样的调整。
提示:你可以设置Transform位置到 0,0,2. 当你移动Finish Line物件的时候,子物件也会跟随,也就是一个父子关系或群组关系的GameObject的作用.

你已经完成了游戏的大部分功能。下一步用一个任务控制脚本来把所有的东西整合在一起,显示游戏的计时器,协调游戏的玩法,和重置场景来开始一个新的游戏。
倒计数
创建一个新的脚本资源,并命名它为GameController.打开这个脚本,删除预先添加的函数,然后添加下面的代码:
static var gameRunning : boolean = true; |
timedOut = true;
gameRunning = false;
}
}
Unity提供GUI控件来让添加文本标签和按钮功能更加容易。gameMessageDisplay变量控制显示在那里。这里你建立了倒计时器,显示在屏幕的顶部。 |

试玩游戏,然后混一会儿直到时间用完,目的是测试倒计时显示和失败的状况。它非常不容易看的清,但是不要担心,你会马上改变它。停止游戏。 |

|
|
有时候你会赢,有时候你会输
你应该显示一个胜利的消息,当英勇的小方块穿过终点线的时候,或者撞上不可见的墙 - 它渴望为完成这个挑战得到一些鼓励!这个消息包含他完成挑战花费的时间。 |
private var missionCompleted : boolean = false; |
然后添加下面的代码到GameController脚本的最后面: |
function MissionComplete() {
|
MissionComplete()检查游戏是否正在运行。如果它正在运行,它设置missionCompleted标记为true,然后gameRunning标志为false. 完成游戏的时间然后被保存下来。 |
if (missionCompleted) {
|
切换到FinishLineDetection脚本,然后修改根据下面部分来修改(新增的部分用注释标记了): |
#pragma strict |
新的代码被数字标出,完成下面的事情: |
- 定义一个公共的变量来指向GameController脚本。你马上会给它赋值。
- 在GameController脚本中调用MissionComplete()来出发胜利的情况。
|
|

要分配gameControllerScript变量,选择Goal GameObject,然后选择InspectorFinish Line Detection,然后点击Game Controller Script边上的原点。选择Main Camera GameObject,最后关闭对话框。 |

|
|

试玩游戏,冲向终点线,避开那些邪恶的阻挡物。当你在规定的时间内完成的时候,检查是否显示正确的消息。 |

停止游戏,然后再次点击Play。测试失败的情况。确保那个逻辑仍然可以工作。 |
改变显示的字体
你也许注意到,特别是如果你用Unity Remote或者你的iOS设备来测试这个游戏,显示游戏消息的字体非常的小。这是一个很好的机会来学习如何导入字体到Unity中。 |

你已经导入你的自定义的字体,并且在你的项目中准备好使用它们了。 |
var gameMessageFont : Font; |
通过改变OnGUI()来改变用于显示标签的字体,就像下面展示的那样: |
function OnGUI() {
|
你通过分配gameMessageFont公共变量为GUI.skin.font来改变字体。 |

预览游戏,并检查使用新字体显示的消息。 |

嗯,好些了! |
它总是在计时 !
下一步创建一个游戏中的按钮来控制游戏的开始和允许玩家在胜利和失败后重新开始游戏。当游戏没有运行的时候你会显示这个按钮。回忆你定义过一个gameRunning标志,用它你可以控制这个按钮是否显示。 |
private var playButtonText = "Play"; |
然后添加一个新的函数叫做startGame()来构建一个新的游戏: |
function startGame() {
|
现在修改OnGUI(),通过添加下面的代码到OnGUI()底部(在所有存在的代码后面),当游戏没有运行的时候来显示这个按钮: |
// The menu button |
最后,设置gameRunning标志为false.只要修改变量存在的那行,调换初始值从true到false: |
static var gameRunning : boolean = false; |
OnGUI使用GUI.Button()函数来放置一个按钮。按钮的文字是一个变量,所以初始它设置为"Play",每次重新开始前是"Play Again" |
if (GameController != null && !GameController.gameRunning) |
你也应该不让发射器,发射障碍物,当游戏还没有开始的时候。添加下面的代码到ObstacleLauncher脚本的Update()头上: |
if (GameController != null && !GameController.gameRunning) |
试玩游戏确认当游戏没有开始的时候,玩家不能移动,障碍物没有被发射。 |
每个小方块需要一个崭新的开始
现在play按钮工作正常了,你也许注意到及时一个新的游戏开始,计时器被设置了,但是游戏的其他方面没有被重置。 |
- 你要在MoveAround脚本中定义一个叫做resetGame()函数来重置玩家的位置到游戏开始的初始位置。
- 你要在ObstacleLauncher脚本里定义一个叫做resetGame()函数来重置障碍物的数量到零。
- 你要循环遍历给定的GameObject列表,包括player和发射器GameObject,调用 GameObject.SendMessage(“resetGame”, …)来调用这个reset.
- 你要在GameController添加重置的逻辑,当用户重置游戏。
但是代码比文字更有说服力。首先打开MoveAround添加下面的遍历和函数: |
var originalPosition : Vector3; |
然后打开ObstacleLauncher脚本,然后添加这个新的函数: |
function resetGame() {
|
下一步打开GameController脚本,然后添加下面变量:var gameObjectsToReset : GameObject []; |
上面这行定义了一个GameObject的数组,这是一个包含resetGame函数的GameObject数组,依此调用它们来完成一个个重置。 |
function startGame() {
|
这段新的代码通过查找所有标记为Enemy标记的GameObejct来清除所有的敌对实例。Destroy()在敌对的GameObject上被调用。这会清除场景中所有的障碍物。 |

设置尺寸为2.数组元素会扩展。分配Player GameObject到 元素0,然后Launcher GameObject到元素1. |

试玩游戏,核对在一次胜利或失败后,游戏完全重置了自己。核对玩家位置重置到原始地方,所有障碍物被清除,而且大概游戏重新开始后障碍物开始再次坠落。
Unity3D for iOS初级教程:Part 3/3(上)的更多相关文章
- Unity3D for iOS初级教程:Part 2/3
转自Unity3D for iOS 这篇文章还可以在这里找到 英语 Learn how to use Unity to make a simple 3D iOS game! 这篇教材是来自教程团队成员 ...
- Unity3D for iOS初级教程:Part 3/3
转自Unity 3D for iOS 这篇文章还可以在这里找到 英语 Learn how to use Unity to make a simple 3D iOS game! 这份教程是由教程团队成员 ...
- Unity3D for iOS初级教程:Part 1/3
转自Unity 3d for ios 这篇文章还可以在这里找到 英语 Learn how to use Unity to make a simple 3D iOS game! 这篇教材是来自教程团队成 ...
- Unity3D for iOS初级教程:Part 3/3(下)
转自:http://www.cnblogs.com/alongu3d/archive/2013/06/01/3111739.html 消息不会自动消除 你基本的游戏功能已经完成了,但是显示一些关于游戏 ...
- Unity3D for iOS初级教程:Part 1/3(下)
转自:http://www.cnblogs.com/alongu3d/archive/2013/06/01/3111735.html 一个手指来统治他们 但是等等,你还没有完全完成! 如果你玩游戏有一 ...
- Unity3D for iOS初级教程:Part 1/3(上)
转自:http://www.cnblogs.com/alongu3d/archive/ 如果图片看不到,请查看原文 这篇教材是来自教程团队成员 Christine Abernathy, 他是Faceb ...
- Coding 初级教程(二)——上传已有项目
Coding 初级教程(二)——上传已有项目 [摘要:方针读者 :已具有 Coding.net 的账号. 本文首要先容若何把项目上传到 Coding.net 上. 分两种环境,一种是项目已归入到 gi ...
- Unity3D新手入门初级教程
根据游戏调查公司 Newzoo 针对全球手机游戏市场所做的调查报告显示,2016年全球游戏市场规模将达到 996 亿美元,其中手机游戏市场将以 21.3% 的增幅获得约 369 亿美元的收入,而中国手 ...
- 新手必看,史上最全的iOS开发教程集锦,没有之一!
最近大火的iPhone XS Max和iPhone XS,不知道有没有同学已经下手了呢?一万三的价位确实让很多人望而却步啊.据说为了赢得中国的用户,专门出了双卡双待的,可想而知中国市场这块“肥肉”人人 ...
随机推荐
- python——inspect模块
inspect模块常用功能 import inspect # 导入inspect模块 inspect.isfunction(fn) # 检测fn是不是函数 inspect.isgenerator((x ...
- java中的线程安全
在Java中,线程的安全实际上指的是内存的安全,这是由操作系统决定的. 目前主流的操作系统都是多任务的,即多个进程同时运行.为了保证安全,每个进程只能访问分配给自己的内存空间,而不能访问别的.分配给别 ...
- 通过阿里云的IOT平台控制ESP8266
通过阿里云的IOT平台控制ESP8266 #include <ESP8266WiFi.h> /* 依赖 PubSubClient 2.4.0 */ #include <PubSubC ...
- nyoj 95-众数问题 (map)
95-众数问题 内存限制:64MB 时间限制:3000ms 特判: No 通过数:16 提交数:29 难度:3 题目描述: 所谓众数,就是对于给定的含有N个元素的多重集合,每个元素在S中出现次数最多的 ...
- ES6学习 let const
1.前言 发现网易云笔记 单纯的记笔记没什么意思,所以今天来博客园写学习感受了,毕设做了休息时间就来写写新学的知识 哈哈哈 !! 2.ES6 就是JavaScript 语言的下一代标准,2015年6月 ...
- 领扣(LeetCode)二维区域和检索 个人题解
给定一个二维矩阵,计算其子矩形范围内元素的总和,该子矩阵的左上角为 (row1, col1) ,右下角为 (row2, col2). 上图子矩阵左上角 (row1, col1) = (2, 1) ,右 ...
- django:runserver实现远程访问
如果是在另一台电脑上web访问要用 python manage.py ip:port (一般使用8000)的形式:监听所有ip用0.0.0.0如下: 1 2 3 python manage.py ru ...
- vux组件的全局注册引入
安装好vux后,要引入全局组件是要在main.js中使用Vue.component引入的,不能直接使用Vue.use,不能直接使用Vue.use,不能直接使用Vue.use import router ...
- 软件测试从业者必备的高频Linux命令
命令 cd 1.如何进入上级目录 cd .. 2.如何进入当前用户主目录 cd ~ 3.如何进入上两级目录 cd ../.. 4.进入当前目录命令 cd . 5.如何进入目录 /usr/isTeste ...
- C# - SPC(Statistical Process Control)系统 - 6西格玛数据决策和Chart模块的开发与实现
Statistical Process Control 简介 统计过程控制(Statistical Process Control)是一种借助数理统计方法的过程控制工具.它对生产过程进行分析评价,根据 ...