【GAD翻译馆】VR100天教程:第一天设置Unity Ball教程
译者:刘鸿(lewis2012,251423807) 审校:王玥亭(玥亭)
我知道,Unity更适合初学者,所以我决定选择Unity。我安装了最新版本的 Unity和Unity绑定的Visual Studio 2017社区版。
好了,我们已经安装了工具包,那接下来呢?
我做的第一件事是通过Unity的Roll-a-ball tutorial.a开始
以下是我在本教程中所学的内容:
游戏设置
场景
场景选项卡为你提供可移动的世界3D视图。在此选项卡中,你可以直接拖拽之前插入到Unity中的对象到指定的位置。
Hierarchy面板
Hierarchy面板用于显示你创建并添加到场景中的Unity对象。
定位
因为我们工作在3D环境中, Unity 有一个3 d坐标系统(x,y,z),如果我们在教程中选择创建球体,你会在右边看到inspector视图,视图中我们可以更改变换一些属性,如位置,旋转和缩放。
X =水平运动
Y =高度运动
Z =垂直运动
材料
如果想改变物体的颜色,我们必须为我们的网格渲染组件创建一个材质,你可以从上面的图片中看到。
如果你选择了球体,在网格渲染组件下的检查器中,你可以选择一种材料来应用于我们的对象。
在本教程中,我们在项目中创建了一个新材料,并使其颜色为红色。然后我们把它应用到我们的球面上,得到了一个红色的球体。
Roll a Ball
在第一个视频演示了如何设置环境和使用一些工具来完成Roll a Ball教程,接下来我们学习的是如何实际移动小球。
刚体
我们需要做的第一件事是在我们的球对象中添加一个刚体组件。它的作用是使球符合到Unity的物理引擎,这样球对象就会受到如重力等物体碰撞和其他属性的影响。
看看这段视频的代码,我们可以学到很多信息:
Unity中脚本的工作方式是连接到Unity游戏对象中,我们可以获取任何附加到游戏中的组件信息。
当我们使用刚性组件时,在上面的示例代码中给出了一个很好的例子:
因为当我们想从我们的刚体组件获取信息时。
公有变量(Public variables)
在查看该函数的其余部分之前,我想指出,如果你要在Unity脚本中创建一个公有(public)的变量,这意味着你可以将其值设置为Unity编辑器中该脚本组件下的代码。
使用组件系统,我们可以很容易地改变文本和设置,当你测试你的游戏代码!
学习Start和Update函数
所以我们有2个函数在代码Start()和FixedUpdate()中使用。这两个都是我们从MonoBehaviour对象继承的方法,它们控制游戏的运行方式。
下面是我发现的更常见的方法
Start()— 只有当你的GameObject在Unity中创建时才运行一次。它用于初始化变量,并在首次创建时创建GameObject的状态。
下一个部分是更新方法(update function )。根据你使用的内容,更新方法(update function )可能需要一些时间来更新你想实现的功能。
每次Unity渲染一帧时,都会调用一次更新方法(update function )。你可能听说过这个术语, 帧每秒?如果我们每秒有60帧,这意味着我们的更新方法(update function )每秒钟能调用60次。
那么什么是帧?如果你有一些动画知识,你会知道图像是由一个接一个动态替换的多图像组成。可以一个图像来说明我的观点,如下图这个gif图像:
这个gif图像实际上是由多个图像组成的一个精灵(sprite)图,每个场景都是循环的。
从我的基本理解来说,这对VR非常重要,如果我们想避免引起晕动症,我们必须做一个达到90 fps的游戏。
但无论如何,这是未来的问题,我甚至不知道如何使用Unity工作!回到更新方法(update function ),我们有:
Update() —这个方法在游戏运行的每帧都会被调用。通过插入调试代码段(Debug.Log("update: " Time.deltaTime);),我进行了自己的调试。打印出自上次update方法被调用以来已经过了多少时间,并发现每个帧的时间不一致。
FixedUpdate() — 类似于Update() 方法,但这段代码在固定时间被调用,这对我们在上面代码中看到的物理计算很好。打印deltaTime,看起来FixedUpdate方法每0.02秒就会被调用。强制达到50帧/秒的帧率。
输入和向量
最后,代码的最后一部分是移动代码。Unity提供了一套方便的api,这使得用户在敲击键盘时很容易检测到。
我们使用 Input.GetAxis。当我们按下箭头键时得到运动的方向,并将这些值存储在一个向量中。
如果你记得高中的一些物理知识,你可能记得一个向量只是一个方向。在我们的代码中,当我们说我们创建一个向量(x,y,z)这意味着我们正在创建了一个指向x,y和z方向上的力。
这就是你在这里看到的:
移动相机
我们在视频系列教程的第三集已经了解了很多关于Unity的东西,在学习移动小球后,我们现在看到运行的游戏中,当我们想让小球滚动时并没有真正移动。
这需要通过使用相机对象来解决的,你在游戏中看到的视图是来自相机的。
所以一种很好的方法是通过将主摄像机对象拖放到我们制作的球体上,使摄像机成为球对象的子对象。
通过这样做,我们使我们的相机相对于我们的球的位置。不幸的是,当我们围绕摄像机移动球时
为了解决这个问题,我们将提供的CameraController脚本添加到我们的相机对象中:
我们所做的是,我们在Start()函数中创建了从相机到玩家的距离,并更新我们的相机,使它始终在LateUpdate()中保持距离
LateUpdate()与其他update()的方式相同,区别在于它是在渲染一帧是被调用的方法。
设置游戏区域
这个部分没有太多内容,只是学习如何通过移动对象来设置我们的环境
创建可收集的对象
这里也没有太多,我们创建了可收藏的物品,玩家可以把球滚过去,我们创建了一个脚本来让球旋转,我们通过抓取GameObject的转换组件和修改旋转来做。
注: Time.deltaTime是自上次调用Update()之后的时间
预制(Prefabs)
但是值得注意的一点是,在我们做了我们想要的对象之后,我们可以将它从hierarchy面板拖放到项目面板的底部中,创建一个预制。
预制是你所创建的对象的模板或克隆。这样,我们就可以创建同一个对象的多个实例。
使用预制的好处是,如果你决定改变游戏对象的组件,而不是一个接一个地改变它们,只要改变预制,你就可以一次性改变所有的实例。
Collecting the Pick-Up Objects
现在事情终于变得更有趣了。在本节中,我们学习了许多涉及到碰撞器的主题,以及游戏中的对象如何与其他对象交互。
从之前的视频中,我们创造了这些立方体物体(它们有自己的刚体),我们可以收集,然而,如果我们将球滚到立方体中,我们会弹回来。
这个问题将在这个视频中得到解决。
碰撞器介绍
当一个有碰撞组件的GameObject碰到另一个带有碰撞组件的GameObject时,我们称之为碰撞。
Unity提供了许多碰撞组件,你可以附加到你的游戏对象上。这些碰撞的形状和大小都不同。目标是选择一个与你的游戏对象形状匹配的碰撞器。
当我们使用一个不同的碰撞器时,比如说一个正方形,当其他物体接触到物体(红色的球体)时,碰撞不会发生,相反,碰撞将从他们接触到正方形的边缘开始。
根据我的理解,我们可以使用一个网格碰撞器来尽可能的接近我们的物体,但是我们需要在我们的游戏对象上进行更多的精细控制,需要进行更多的计算,从而导致性能下降。
TLDR:如果你绝对必须使用复杂的碰撞器,否则我们应该尝试使用更基本的形状碰撞器。
这个方法在每次我们的球碰到另一个碰撞器时被调用,我们通过一个碰撞器对象,它可以访问我们撞到的游戏对象。
注意,我们的对象上有所谓的tag标志,这就是我们在Unity中如何确定相互碰撞的对象。在hierarchy面板中的每个GameObject上,可以创建并附加一个tag标志。从上面的代码中可以看出,我们可以使用tag标志来帮助识别与哪个游戏对象相碰撞。
在我们找到了我们想要的tag标志后,我们可以做任何我们想做的事情!
性能优化
虽然可能不太重要,但我们简要地说过,有两种类型的碰撞,静态和动态的碰撞。
正如你所期望的,静态碰撞器是不动的物体,动态的物体是运动的物体。要记住的重要一点是,静态碰撞器被统一缓存起来,这样我们就可以获得性能优势,但是如果你计划更改和移动一个静态的游戏对象,这将导致Unity不断地缓存对象,这将成为性能问题!
为了使一个游戏对象成为一个动态的碰撞器,将使它受到Unity的物理引擎的影响(增加一个刚体组件)。
显示分数和文本
游戏是“技术”的,但是用户永远不会知道。在视频系列教程的最后一集中,我们学习了如何使用Unity的UI系统。
用户界面(UI)
你可以通过在hierarchy面板中右键单击,在Unity中创建一个GameObject的方式创建一个UI元素,但是一个很大的区别是所有UI元素都是Canvas GameObject的子元素。
另一件事是,当你在“游戏”选项卡中时,“画布”实际上直接显示在屏幕上,而不是“场景”选项卡的一部分,实际上它是完全不一样的。
画布覆盖了整个游戏选项卡的屏幕,对于我们的UI GameObject,我们有使用Rect Transform 而不是Transform。
在某种程度上,它类似于一个正常的游戏对象,你仍然可以拖动对象,有一个巧妙的小技巧,帮助你定位文本,就是点击我们的Rect变换组件左上角的方块按钮,你会得到这个:
如果你按住alt键并点击一个方块,你的文字将会自动进入9个空格中的一个!很好!
如何使用我们的UI组件
看看视频中创建的代码:
我们创建了一个类型为Text的公共变量,你可以通过将hierarchy 面板中的Text对象拖放到脚本组件的变量槽中来分配值。
使用UI游戏对象时要记住的一件非常重要的事情是包含以下代码:
否则,Unity不会知道你想引用的任何UI对象。
唯一新的重要的部分是SetCountText()函数,它是我们看到如何与UI对象交互的地方:
看起来很简单,对吧? 你可以获得UI对象,并将它设置为任何你想要的文本。简单!
结论
做这个写作总结可能比Unity的学习更困难,这只是第一天!
但是没关系。我们刚刚开始了解Unity,我相信随着我们的进步,我们会看到类似碰撞,刚体,UI的东西,我不需要再做这个了。我真的希望如此。我真的。
无论如何,这是第一天的结束!我希望你从中学到一些有价值的东西!
访问VR挑战100天的内容表。
原文作者未做权利声明,视为共享知识产权进入公共领域,自动获得授权。