这篇文章还可以在这里找到 英语
这篇教材是来自教程团队成员 Christine Abernathy, 他是Facebook的开发支持团队的工程师。
Unity是最为流行的游戏引擎之一。这是有充分缘由的:Unity有一个让它非常容易上手的强大的可视化编辑器,功能强大,好的社区支持,有吸引力的价格,等等!
如果你渴望尝试Unity,没有比这篇教程更适合你的了!在这篇教程中,你会学习如何用Unity创建一个简单的iOS游戏 – 并且之前不需要有任何经验!:]
在这篇教程中,你要创建的这个简单游戏是让玩家在限定的时间内,绕过沿途的障碍物顺利达到终点。
在过程中,会向你介绍Unity的开发环境和工作流程,并且学习游戏设计的基本概念。
这篇份教程将会分为三个部分:
在第一部分中,通过创建一个游戏,这个游戏具有一个带有控制机制的简单角色,通过这个游戏使你学会使用Unity的基本操作。你也会学习如何将的项目部署到iOS平台上。
在第二部分中,你会掌握如何使用内建的控制器对象和标准库中的脚本来增强角色的移动;如何用Unity Remote来调试;如何美化游戏的场景。
在第三部分中,你将会添加游戏规则到你的项目中,并且建立起游戏设计的概念,这些概念包括添加预制件,计时器,菜单和音效来增强游戏的体验。
准备好了添加一个强大的新框架到你的技能栏里了吗?请继续阅读!:]
让我们开始吧
当你完成这个系列的教程,你就会熟悉Unity的开发工作流,它包括四个基本的部分:
- 在Unity Editor中搭建你的游戏场景
- 用MonoDelelop Editor撰写脚本
- 用Unity Romote远程调试
- 用Unity Editor发布到你的iOS设备上
在教程的第一部分中,你要安装Unity,学习编辑器界面的基本功能,然后通过创建一个项目,来向你介绍游戏基本的概念。
第一部分结束时,你会在游戏中得到有一个可以通过触摸触发而移动的角色。你也会在Unity Editor和iOS设备上测试你的项目。
这篇教程使用的是Unity版本4 – 如果你还没有安装,那就前去下载Unity吧。
Unity提供了一个功能完整的, 具有30天免费试用时间的专业版本。这个版本允许你开发游戏,并且可以部署游戏,并运行在iOS平台上。虽然Unity可以运行在Mac和Windows平台上,这份教程是基于Mac环境的。
注意:Unity软件包是相当大的,几乎接近1G, 根据你的网络链接的速度,它会花一些时间来下载。如果你想要马上开始,请提前下载好。:]
创建项目
当你下载并且安装完Unity之后,开启Unity。如果这是你第一次启动Unity, 会提示你激活你的程序。选择Activate the free 30-day trial of Unity Pro选项,就像下面截屏所示:
然后你需要创建一个Unity账号,如果你还没有的话,确认你的邮件地址,然后通过Unity登录。
当你登录后,你会被问及一些问题。如果你翻到列表的最下面,然后点击”Not Right Now.”,这样你就可以跳过这些问题:]。最后,你就可以开始使用Unity了。
到了这步,一个缺省的项目创建好并呈现在你的面前 – 就像下面这样:
扔掉那个项目,然后通过选择菜单中的FileNew Project来创建一个新的项目。一个项目导向会呈现在你面前:
在项目向导中,点击”Set”然后导览到你想要保存这个项目的文件夹下。输入DashAndZag作为项目的名称,点击“保存”,最后是”Create Project”。(会询问你是否想要保存之前打开的那个缺省的项目,但是你可以选择不这样做,除非基于某种原因你想保留它…)
注意:在项目创建的阶段,这个项目导览包含了一些你可以导入的标准库。目前先忽略这点。你会在这篇教程的后面导入你需要的库。
Unity会关闭当前的项目然后再次用你新的项目启动:
啊哈,一个全新的画布!但是这些控件条,窗口和标签栏究竟是啥?我们要从哪里开始呢?
开始了解UI吧…
值得花一些时间来调整一个真正适合你的Unity Editor界面,所以让我们瞧一瞧。在右上角编辑器的Layout标签栏那里停一下。将视窗的模式改为Wide:
这里将你看到打散的各个部分,每个部分都用高亮标出:
- 项目视图:你的Unity项目包含的资源目录的内容会在这个栏目里显示出来。这里有脚本,场景,预制件和其他你创建的Unity对象。
- Hierarchy(层次列表)视图:这里包含了当前场景中的GameObject。在Unity游戏中,每个出现的对象称之为GameObject。这些对象可以是你从the GameObject菜单下创建的简单的对象,或者是你导入的资源。你那个初始的项目包含一个GameObject:主摄像头。
- 工具条:工具条允许你在场景视图或游戏视图中操作对象,来控制你的编辑器视图如何被显示,也能控制编辑器中游戏的预览。
- 场景视图:在这个视图里,你可以摆放你的GameObject的位置来搭建你的游戏。这个场景视图包括了一个场景Gizmo(就是右上角带有坐标轴的那个东东)它标明了场景镜头的当前方位。
- 游戏视图:这是一个来自你游戏中摄像头的视角。当你点击工具栏上面的Play按钮,你会看到这个游戏视图。另外,你也可以通过窗口顶部的标签来切换游戏和场景视图。
- Inspector(检查器):这个东西提供了被选中的GameObject的进一步详细信息。你可以改变这些对象的属性,例如尺寸,位置,或者是关联的脚本来改变这个GameObject的行为。
你将会很熟练的使用工具栏中的变换工具来放置GameObject,并在场景视图中逛逛。好吧,让我们转到下节:
获得一个把手
Hand工具让你控制场景中你的视角
最好理解Hand工具的方式是想象你自己掉到了3D场景中,周围有很多GameObject. 在你前面的物件是可见的,而那些在你身后的是不可见的。
你或许希望在场景中后退几步,这样可以看到更大的视角,向左或向右移动看见其他物件,或者旋转和平移看看你身后有些啥。这个Hand工具就是为你做这些的。
当你开始添加越来越多的GameObject后,你会发现在放置GameObject之前你会越来越多的使用这个工具来在场景中调整你的视角。
要看看Hand工具是如何工作的,首先选中它(在工具条的最左边),然后从Hierarchy视图中选择主摄像头(只是让你在场景的视图中有东西可以看到)。你可以拖动画布来移动整个场景。
要缩放,你可以使用你的鼠标滚轮,或者按住Control键并拖动鼠标。你可以通过按住Option键,拖动鼠标来旋转。如果你想在任何时候重置你的视角,你可以点击场景右上角Gizmo的其中一个轴。
把玩一会Hand工具,直到你熟练在场景中移动,并可以使用Control和Option组合来缩放和旋转。
你经常要在Hand工具和其他工具之间切换,所以记住它的快捷键是有必要的。缺省情况下,这些按键一个挨着一个,在你的键盘的左上角 – Q, W, E, 和R,分别代表Hand, Move, Rotate和Scale.
注意:Hand工具并没有移动物件。它仅仅改变你场景的视角,所以它看上去就好像物件被移动了。使用各种Hand工具选项练习在场景中移动。
移动它或放开它
使用Move工具,你可以在3D空间里移动GameObject。
选择主摄像头(如果你在场景视图里没有看到它,可以再Hierarchy视图中双击它),然后点击Move工具。你应该会看到在主摄像头边上出现一个gizmo,有箭头代表三个轴。通过这些,你可以移动这个物件:
红色的箭头代表X轴,绿色箭头是y轴,然后蓝色箭头是z轴。你可以通过选中这个物件,按住鼠标左键,然后在gizmo中拖动,来移动一个GameObject.
选中主摄像头,移动一下。看一下在Inspector中的transform组件。Position栏目中有x, y和z值代表GameObject的位置。当你移动物件的时候,注意这些值的变化。
你可以改变GameObject的transform位置,通过使用Move工具,或者直接在这些输入区域输入你想要的位置。
如果你只想在一个方向移动物件,选择gizmo中相应的轴,按住左键,拖动那个轴。通过仅仅在x轴移动主摄像头来测试这点,在Inspector中查看,仅有x-position的值改变了。在y和z轴重复同样的动作。
你已经知道如何在场景中变换你的个人的视角,也知道了在场景中如何移动物件。到目前为止都还不错哦!
你带着我转一转
Rotate工具让你在3D空间旋转GameObject
要了解Rotate工具,并知道如何使用它,更深入的讨论场景的Gizmo是很有必要的。在场景视图右上角可以找到场景的Gizmo,不同的视图有着不同的模式。
有一种模式(如左下方那个图)让你通过一个3D透视,以一种自由的方式观察你的场景。如果你想要更好的表现你的游戏在3D空间的样子,这是非常有用的。
你可以点击gizmo下面的文字,切换到isometric视角(如右下方图片展示的那样)。这种模式当一个物件被旋转的时候,它更加具有可视性。
另一个模式是x轴视图,它让你能够观察你的场景,就好像沿着x轴从上往下看。如果你想要在y-或z-轴移动物件,而保持x-轴不变时,这种模式非常有用。
在类似的方式下,你有y-和z-轴模式让你从那个方向获得场景的视角。
选中主摄像头。在Gizmo上点右键,选择Free, 切换到自由透视模式。
然后点击gizmo下面的文字,在isometric和perspective模式之间切换。反复点击x- y-和z-轴模式观察场景Gizmo和场景视角的变化。
再次选择自由视角来测试旋转。主摄像头仍然被选中的情况下,点击Rotate工具。你应该看见一个Gizmo出现在主摄像头上,它包含了代表三个旋转轴的不同颜色的圆环。
左键点击主摄像头的的中心,用你的鼠标拖动旋转主摄像头。当你旋转这个物件的时候,注意Inspector的TransformRotation属性的变化。注意,你可以手动的编辑Inspector中这些值,如果你愿意的话。
点击主摄像头中心位置,你是要打算沿着所有的轴自由的旋转。通过点击代表某个轴的颜色的圆环,你可以沿着这根轴旋转GameObject。举例来说,若只要沿着x-轴旋转,点击红圈选中它,然后按住鼠标拖动来旋转这个物件。若只要沿着y或z轴旋转,重复相同的步骤。
一切都归结为视点
另一个关键的值得学习的概念是局部和全局(世界)的视角的区别。
通过InspectorTransformRotation字段,重置主摄像头的旋转角度到0,0,0。点击那个叫做”local”的工具条。然后选择移动工具,这样你可以看见场景的Gizmo:
注意场景的Gizmo和主摄像头的Gizmo方向是一致。在场景中,x-轴指向同一个方向,并且y-和z-轴也一样。现在用Inspector的设置TransformRotation值为0, 0 -20,沿着z-轴来旋转主摄像头.
注意主摄像头的Gizmo现在绕着z-轴旋转 – 这表示物件的轴在它自己的局部坐标系中。这与场景Gizmo是不同的,场景坐标显示的是全局空间的操作。切换到全局视角来查看之间的不同。
在这篇教程的后面,你将会学习如何移动GameObject,发现你会发现当移动物体时,使用的你指定的不同空间(世界或者局部)的差异。
看一下被旋转的主摄像头,如果你在局部坐标控件的x-方向移动它,它会在与你在世界坐标中的x方向移动它最终的位置不一样。把这点记在你的脑子里,今后会有用!
在你继续之前,重置旋转角度到0, 0,0,让我们回到一个干净的状态。
缩放工具
缩放工具允许你,你已经猜到,在尺寸上缩放GameObject
与其他GameObject的操作工具比较,你只能够改变三个轴中的一个,当然你可以选择改变InspectorTransform组件来替代这个工具。
选择主摄像头,然后注意缩放的Gizmo,在每个轴的末端包含一个方块把手,还有一个在中间。
要在所有轴方向自由的缩放,选择物件中间的方块,然后左击,然后向上移动让GameObject放大,向下移动让它变小。看一看InspectorTransformScale的属性。当你放大或缩小这个物件的时候,你应该看到数字变大或变小。
通过选择红色的gizmo把手,测试沿着x轴缩放,然后握住向外移动把手。用Inspector的TransformScale x-值来核对只有一个改变了。也试一试y和z轴。
当你玩转了这些控制按钮后,在InspectorTransform栏目下重置主摄像头为下面的设置:
- Position: 0,1,-10
- Rotation: 0,0,0
- Scale: 1,1,1
你的Transform菜单应该看上去像这样:
在这份教程中,你将要学习其他编辑器界面组件。包括使用Play按钮来试玩一个游戏和使用Unity调试器。
除了孤独没有其他:添加GameObject
现在你已近涉及了一些基本概念,你要开始添加GameObject来给摄像头作伴 – 只有它自己,确实很孤独:]
现在相机面对的是一个非常荒凉的世界。 不要害怕 – 准备来添加一个方块类型的GameObject来代表主角,还有一个平面类型的GameObject来代表主角在上面移动的地板。
当你用Unity来设计一个游戏,最好的实践是对于要开发的游戏先不要用任何花哨的资源来代表一个主角。在这种方式下,你可以关注优化游戏玩法和主角的移动上,而不被其他图像元素所分心。
另外一个注意点是Unity是一个很好的游戏引擎,但是你不要想用它来创建图像资源。在图形部门,那里应该有许多工具都是相当不错
的,而Unity善于从范围较广的那些工具中导入资源。
通常情况下,典型的游戏开发的分工是,游戏开发使用Unity开发游戏玩法,而美术设计并行的使用他们喜欢的图像工具创建各种资源。当两方工作收敛时,这时候导入图像资源来给游戏增色是合理的。
现在你已近认知了那点,让我们开始吧!通过选择Game ObjectCreate OtherPlane.添加一个平面类型的GameObject来代表地面。
这个新的平面GameObject应该出现在Hierarchy视图中。在Hierarchy视图中选择地面,然后使用Inspector设置TransformPosition为 0,0,0.再用Inspector来放大它到50, 1, 50.你的场景将会看上去像这样:
下一步,你将要添加主角GameObject,在你的游戏中将会用一个方块来表示。就是这样的,英勇的小方块!
选择Game ObjectCreate OtherCube,然后一个新的方块类型的GameObject将会出现在Hierarchy视图中。在Hierarchy视图中选择这个方块,然后用Inspector设置TransformPosition为0,0,0.你的场景应该看上去像这样:
点击移动工具,然后点击场景Gizmo的y轴来只在y轴方向有约束的移动。向上移动英勇的小方块让它稍稍高于地面(地板)。你也可以设置变换位置到0,1,0来向上移动这个立方体一点点。
现在到了激动人心的时刻了 – 点击在Unity编辑器的工具条上的Play按钮(在最上面)来预览你的游戏:
你正在使用 Unity编辑器测试你的游戏。这个编辑器应该切换到游戏视图,并且你应该看到像这样的一些东西
你所看见的游戏的视图是通过你的场景中的主摄像头看见的东西。你的主角,这个英勇的小方块,出现在远处,地面的上方 – 一个人的世界,但是勇敢的屹立在那里!
因为你还没有添加任何其他组件来改变玩家的行为,所以游戏中没有啥事情会发生。另外场景也有一些暗。下一步,你可以首先添加一个光源到你的场景中。
通过再次点击Play按钮停止游戏预览。回到场景视图,添加一个光源。选择Game ObjectCreate OtherPoint Light。通常情况下,在今后调整它的位置前移动光源到原点。使用Inspector设置transform position为0,0,0.
现在调整光源的高度和亮度,让你可以看清场景的更多范围。这里有个提示:使用移动工具,然后沿着y轴做有约束的移动。
要调整亮度,修改Light组件中的Range和Intensity设置。使用”手型”工具来旋转,如果你希望得到场景更好的视角。
一个好的方式来观察你是否有了足够的光线是使用Game面板切换到Game视图(相当于点击Play按钮)。来回尝试直到你可以看见你的角色:
当你调整完之后,点击Play按钮来合适你的修改。当你切换到游戏视图,你的视图应该同下面的相似:
恭喜你,你已近添加了这个教程在这个阶段你需要的所有的GameObject!记住,作为一个好的实践,你首先要把注意力放在游戏玩法上,然后再添加图像元素。
既然你已经做了一些有意义的事情,继续前进,保存项目中的场景。一个项目可以有一个或多个场景组成。在游戏中,你可以认为一个场景等同于游戏的一关。
在这个教程中,你保存教程的每个部分作为一个场景。这是人为制造魔种游戏关卡的概念,但是它让你可以从一个场景到另一个场景,来重用那些资源。
要保存场景,选择FileSave Scene,在Save Scene对话框中,命名你的场景为Level_1。你的项目视图应该被你刚才创建的场景所更新。
开始移动:事件函数
游戏目前太静态了!它迫切需要运动让它动起来。
你可以通过创建你自己的脚本或者使用预先打包的脚本关联到相关的GameObject来执行一个动作来添加移动。举例来说,在这个教程的第一部分,你将会创建一个脚本,当玩家被触碰的时候,移动你的角色。你创建的这个脚本需要响应触摸事件来改变英勇的小方块的位置和旋转角度。
Unity支持以下这些语言来实现脚本化:JavaScript, C#,和 Boo。在这个教材里,你会用到JavaScript. Unity的脚本语言包括预先定义的事件函数,你可以使用这些函数来定义某个GameObject的行为。
- 你将要经常用到的事件函数是Update()函数。如果你在你的脚本里定义这个函数,它会在每帧被调用一次。你的游戏显示的内容每帧会被重绘一次,因此Update函数在特定的帧率下负责显示的更新。
一个游戏运行在每秒一定数量的帧率下,另外有一件是需要记住的事是这个帧率非常依赖游戏运行的平台,并且还会被被其他应用占用操作系统的资源。这里的意思是你不应该做任何事件敏感的事情,并且你不能假设它会以固定的频率被调用。 - 另外一个预先定义的事件函数,FixedUpdate(),会被已固定的频率, 独立于刚才提到的帧率来调用。如果你的脚本定义了这个函数,它会以固定的间隔被调用(调用和调用之间与Update方法比较有很大的不同)。
在FixedUpdate函数中,你应该来处理任何物理相关的工作,因为物理的计算是非常时间敏感的。举例来说,你可以有一个游戏对象使用物理引擎,例如刚体(你会在之后学习到更多这方面的信息)。当这个物件与其他物件碰撞后,你想要计算作用于物件的力,那你就应该在FixedUpdate()函数里做这件事。
对于像是改变物件的位置或旋转角度等操作,最好是在Update()函数里去做。 - 第三个有用的函数是Start(),它会在第一帧更新发生之前被调用。你一般会把初始化的操作放在这里。
- 最后,Awake()函数当游戏开始的时候被调用。它是另外一个放置初始化代码的好地方。
对对碰
让我们来试一试。通过选择AssetsCreateJavascript创建一个新的脚本。一个带有缺省名字为NewBehaviorScript新的脚本会出现在项目视图中。在脚本的名字中单击,然后重新命名它为MoveSimple。
双击脚本打开它。它应该在捆绑Unity编辑器的MonoDevelop中打开,然后包含下列代码:
#pragma strict function Start () { } function Update () { } |
Start()和Update函数已经为你创建好了,因为它们是常常用到的函数。你现在不需要Start()函数。在#pragma行后面,添加下面的变量来控制英勇的小方块的移动和旋转速度:
var speed : float = 3.0; var rotateSpeed : float = 10.0; |
用之后的代码替换空的Update()函数:
function Update () { // Detect mouse left clicks if (Input.GetMouseButtonDown(0)) { // Check if the GameObject is clicked by casting a // Ray from the main camera to the touched position. var ray : Ray = Camera.main.ScreenPointToRay (Input.mousePosition); var hit : RaycastHit; // Cast a ray of distance 100, and check if this // collider is hit. if (collider.Raycast (ray, hit, 100.0)) { // Log a debug message Debug.Log("Moving the target"); // Move the target forward transform.Translate(Vector3.forward * speed); // Rotate the target along the y-axis transform.Rotate(Vector3.up * rotateSpeed); } else { // Clear the debug message Debug.Log(""); } } } |
保存你的修改。
这段代码首先查看鼠标的点击事件,特指来之鼠标左键的输入。参数“0”表示左击,“1”表示右击,“2”表示中键点击,当我们使用GetMouseButtonDown函数的时候。如果点击被监测到,那么代码构建一条从主摄像头到鼠标点击位置的射线。
collider.Raycast()函数监测到关联这个脚本的碰撞体是否被射线命中。如果碰撞体命中,这个collider.Raycast()调用返回true.这个函数有三个参数:
- 你构建的射线。
- 一个RaycastHit对象,如果碰撞发生,它会包含更多的信息。
- 一个射线长度的参数。
假设有一个true的结果,后面的代码根据speed变量朝前轻推你的角色,以及基于rotateSpeed变量旋转你的角色。transform.Translate()来移动GameObject的位置,通过它的Vector3输入来指定方向和距离。
Vector3是一个3D的向量,表示物件的方向和长度,或矢量。这个向量可以打散成x,y和z三个部分。
在代码中,你英勇的小方块是朝前方移动一个乘上速度的变量的的距离。Vector3.forward等同于Vector3(0,0,1),并且速度的乘数是3,将会使方块移动Vector3(0,0,3)
角色移动的方向是在角色的局部空间里。要体验这个方向,选中方块,然后使用move工具,然后查看z轴方向。那是角色将要移动的方向。
transform.Rotate()函数根据Vector3输入的一个角度旋转GameObject。欧拉角被用作描述GameObject的旋转。在这个旋转的案例里,物件会沿着z轴旋转欧拉角z度,沿着x轴是欧拉角x度,最后沿着y轴代表欧拉角y度。
在上面的代码里,使用Vector3.up或者Vector(0, 1, 0)来旋转角色,它表示沿着y轴旋转。这个旋转角度是乘上了旋转速度。这个旋转是相对于角色的局部坐标系的。所以你英勇的小方块会沿着它的y轴旋转,正如你所知道的,有别于沿着世界坐标系旋转。
注意:一个真实的游戏不会使用这种类型的移动来控制一个角色。它们用在这里目的是简单的演示涉及移动GameObject的基本概念,在这个教程之后的部分被更加合理的移动所替代。
这段代码里包含了两个Debug.Log()语句。当游戏运行的时候,这个日志输出被打印到Unity的控制台。你可以在Unity编辑器的底部看到最后的日志的输出。你也可以通过选择WindowConsole打开控制台来查看日志的输出,也包括清除日志。
你也可以把目光保留在Unity编辑器的底部,关注在日志的输出上,那里有任何脚本的错误会被显示出来。
通过代码,现在你已经定义了一个行为。你可以分配这个脚本到一个GameObject上。在Hierarchy视图中选择那个方块,然后选择ComponentScriptsMove Simple。这步称之为添加一个脚本行为到一个GameObject,你只要选择你已经创建的(名叫MoveSimple)的脚本。
注意Inspector中现在包含了一个Move Simple脚本栏。你在代码中定义的公共变量,speed和rotateSpeed,在Inspector视图中可见了。你可以在不需要修改脚本的前提下,修改这些变量改变被关联的GameObject行为.
这个意思就是,如果你有两个角色在场景中都带有MoveSimple脚本关联到它们,在InspectorMove SimpleSpeed 字段下,通过增加speed的值,来让一个角色比另外一个移动的快一些。
点击Play来试玩游戏,触碰角色一下,然后注意在Inspector中改变的transform position和rotation属性。
注意transform position从0,1,0开始变化到0,1,3 – 换句话说,在z轴方向有3单位的移动,是因为speed的乘数的关系。旋转也从1,1,1变换到1, 10, 1, 这个非常接近rotateSpeed乘数。
当游戏运行的时候,你可以在Inspector中改变速度和旋转的变量。在点击角色后,增加速度并且观察变换位置。
停止游戏,然后注意观察速度和旋转角度变量被设置会它们原来的值。任何你在玩游戏的过程中改变的都是临时的。这让你有机会捣鼓各种设置,然后返回最初的设置状态当你已经完成你的预览。如果你想要持久的变化,你可以在测试游戏之前再次这样做。
注意当你玩游戏的时候,根据玩家是否被点击或不被点击,控制台记录准确的调试信息。
在摄像头上也来做一边
你会注意到当你移动英勇的小方块时,他离开摄像头越来越远 – 这不是一个好的感觉。就像一个负责任的家长,你希望通过修改你的游戏,让主摄像头跟追在你的角色后面,并保持固定的距离。这是第三人称游戏典型的手法。
选择AssetsImport PackageScripts然后在Items to Import栏目的中,仅选择SmoothFollow脚本,然后点击Import
注意:如果你没有得到import selection对话框,当你选择AssetsImport PackageScripts,那么试图退出Unity然后重新启动。这点对我来说是有效的。
在你的项目视图中一个新的Standard Assets文件夹应该会出现在那里。如果你导览到它的子文件夹下,你应该可以看到也SmoothFollow的脚本。双击这个脚本在MonoDevelop中打开它,这样你看到代码的关键部分。
var target : Transform; |
上面代表用于被跟踪目标的公共变量。目标的位置信息用来设置跟随者的位置和旋转角度。
跟随者的位置和旋转角度在LateUpdate()中设置,这是另一个预先定义的事件函数。这个函数在UPdate()函数完成后被调用。 你可以将依赖那些在Update()发生的操作的代码放到那里。
当英勇的小方块的位置和旋转在MoveSimple脚本中定义的Update()改变后,这个摄像头可以在SmoothFollow脚本的LateUpdate()中更新它的自己位置和旋转角度。
.. var wantedRotationAngle = target.eulerAngles.y; // 1 var currentRotationAngle = transform.eulerAngles.y; .. currentRotationAngle = Mathf.LerpAngle (currentRotationAngle, wantedRotationAngle, rotationDamping * Time.deltaTime); .. var currentRotation = Quaternion.Euler (0, currentRotationAngle, 0); .. transform.position = target.position; // 2 transform.position -= currentRotation * Vector3.forward * distance; transform.position.y = currentHeight; .. transform.LookAt (target); // 3 .. |
这里列举上面代码的关键点:
- 计算跟随者需要的旋转的角度,来匹配目标的旋转。这个旋转沿着y轴。
- 依赖与distance变量的偏移来让跟随者保持在目标后面。也使用来之#1的结果沿着y轴旋转跟随者。最后确保跟随者以高于目标一个固定的高度。
- 确保跟随者总是面对目标
现在关联脚本到主摄像头。选择主摄像头在Hierarchy视图中,然后选择ComponentCamera ControlSmooth Follow:
核对那个为Smooth Follow的新栏目已被添加到主摄像头的Inspector中。
注意在这点上,Target变量没有被赋值,有一个None在它边上。你想要分配一个方块GameObject到这个输入上。当主摄像头仍然被选中的前提下,然后在Inspector中Smooth Follow脚本可见,拖动方块GameObject从Hierarchyshi视图到Target变量。另外一个选项是,你可以点击在Target值边上那个带有一个点的小圆圈来得到一个物件的列表来选择。
Target变量应该链接到方块(你的角色)。
点击Play按钮。你应该立即在视图里看到变化,就像你从一个给定高度向下看着玩家。点击玩家来移动它,然后观察摄像头如何跟随玩家。注意在Inspector中的主摄像头位置信息,然后它在英勇小方块移动时的变化。
停止游戏,然后进入下一步之前保存场景。
部署到iOS上
如果你像我那样,你会迫不及待的想看看这如何在iOS设备上运行的。:]好消息是试用版的Unity Pro允许你在iOS上测试你的项目。
在实际设备上测试你的Unity项目是一个好的实践(i.e. 不是模拟器)。你不想让你的测试只到模拟器为止,即是你只能做到这点。因为游戏开发特别依赖相关的硬件,你应该在实际的设备上测试,这样你可以尽早发现性能上的问题。.
要部署到一个iOS设备上,你需要注册一个Apple的开发者账号,这样才可以有设备部署能力。如果你还没有,去苹果那里,花掉99美金 – 我们在这里等你.:]
Unity可以为你的游戏创建一个Xcode项目,这让你可以部署到一个iOS设备上。要完成这步,选择FileBuild Settings:
选择iOS平台,然后点击Switch Platform. 然后点击Player Setting按钮,你可以在Build Settings对话框的底部找到这个按钮。Unity编辑器的Inspector应该显示Player Settings,这里可以定製你的iOS部署所需要的参数。根据下面来修改:
Resolution and Presentation
- Default Orientation: Landscape Left
其他设置
- Bundle Identifier: 需要Bundle Identifier来正确在你的设备上构建你的应用。
- SDK Version: Device SDK
- Target iOS Version: 4.3
回到Build Settings对话框。在Build section的场景列表中添加那个要生成Xcode项目的场景。因为你的项目仅有一个场景,这里不用动脑。通过点击Add Current按钮来添加Level_1场景。
点击Build按钮来启动构建的过程。你会被问要指定的位置来保存这个Xcode项目。导览到你想要保存的的位置来保存你的xcode项目,在Save As字段中输入DashAndZag,然后选择保存。
Unity会创建这个Xcode项目,然后打开包含xcode项目文件的文件夹。这个项目会有一个叫做Unity-iPhne.xcodeproj的文件。
用Xcode打开这个项目,确保scheme设置为Unity-iPhone,选择你的设备,然后编译这个项目。
运行这个应用。你应该首先观察到一个启动的屏幕作为Unity缺省的logo.然后,你的游戏应该出现了:
触碰这个英勇的小方块然后让它四处移动。你已经构建和部署了你的第一个Unity项目在iOS上了。
一个手指来统治他们
但是等等,你还没有完全完成!
如果你玩游戏有一会,你会注意到有些奇怪的事情。你可以通过一个手指来移动方块,但是当你用两个手指离开它相同的距离方块也可以被移动。这是什么回事呢?
从你的MoveSimple脚本中回忆起这行:
var ray : Ray = Camera.main.ScreenPointToRay (Input.mousePosition); |
它创建了一条从摄像头到触摸点的射线。触摸点用Input.mousePosition来表示。当你在iOS设备上运行的时候,Input.mousePosition是作为所有当前触摸点平均位置来计算的。放置你的手指,若平均值落在角色上,就会让角色移动!
你应该修正这点来避免困扰用户。你可以使用Unity中可以使用的触摸相关函数来监测触摸事件,并且找到一个更加精确的触摸位置。
打开你的MoveSimple脚本。在文件的最上面(其他变量所在的位置)添加一个标志,来指示你可以使用触摸输入:
private var isTouchDevice : boolean = false; |
你这样做了后,你就可以测试运行在iOS和Unity编辑器上。如果你只打算在iOS上测试,那么你可以跳过触摸检查的逻辑,然后简单的使用触摸相关的函数。
下一步添加一个Awake()函数,来完成一个运行时的检查,探知游戏是否运行在一个iOS环境下。这个Awake()函数仅仅被调用一次,就是当游戏加载的时候:
function Awake() { if (Application.platform == RuntimePlatform.IPhonePlayer) isTouchDevice = true; else isTouchDevice = false; } |
Application.platform返回游戏正在运行的平台。RuntimePlatform.IPhonePlayer指示游戏正运行在iOS上。
最后,根据下面修改你的Update()函数来处理触摸输入:
function Update () { var clickDetected : boolean; var touchPosition : Vector3; // Detect click and calculate touch position if (isTouchDevice) { clickDetected = (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began); touchPosition = Input.GetTouch(0).position; } else { clickDetected = (Input.GetMouseButtonDown(0)); touchPosition = Input.mousePosition; } // Detect clicks if (clickDetected) { // Check if the GameObject is clicked by casting a // Ray from the main camera to the touched position. var ray : Ray = Camera.main.ScreenPointToRay (touchPosition); var hit : RaycastHit; ... |
保存你的修改。
你正在使用两个新的变量,clickDetected和touchPosition,来监测点击和保存点击的位置。如果在iOS上运行,你通过检查触摸是在开始状态来判断点击。然后根据首个触摸来计算点击的位置。如果你没有运行在iOS上,逻辑和之前的一样。
在重新构建项目之前,关闭Xcode项目。现在重新在Unity中的Build Settings对话框里构建。如果出现带有一个关于构建的文件夹已经存在的警告,选择Replace.
当Xcode项目构建完成,打开它,然后在你的iOS设备上运行。核对你可以移动英勇的小方块,而且让你用两个手指移动它的错误已经消失了。
向哪里进发?
恭喜你已经完成学习用Unity开发的基础部分,和如何部署到iOS上!这里有一些从项目开始到目前为止的所有的代码下载: Unity Project, Xcode Project.
这份教程的下个部分,通过增强英勇的小方块的移动和改善场景,你会构建这个非常简单的游戏。你也会做一些调试的工作!
在此期间,如果你有任何关于到目前位置你所做的问题或建议,请跳转到论坛中的相关会话中!
这篇教材是来自教程团队成员 Christine Abernathy, 他是Facebook的开发支持团队的工程师。