【GAD翻译馆】VR100天教程:第四天通过Unity Space Shooter教程III

发表于2017-10-31
评论3 1.8k浏览

译者:刘鸿(lewis2012     审校:王玥亭(玥亭)

今天我们回到VR教程第四天,我们将通过添加剩下的UI,敌人产生系统,然后创建一个结束游戏状态来完成这个Unity Space Shooter游戏。

所以,如果没有其他事情,让我们开始吧!

 

音频

要为游戏创建音频,我们需要添加一个音频源组件到我们的游戏对象。

在音频源组件中,我们将音乐文件添加到AudioClip中。

添加音频源组件的一种快捷简单的方法是将你的音乐文件拖放到你想要添加的游戏对象上。

有很多控件可以使用。在这种情况下最重要的是:

1)播放唤醒,当创建此AudioSource所连接的GameObject时播放声音

2)循环,重复播放音乐

3)音量,声音大小

 

在小行星上增加爆炸声音

音频样本已经在教程中全部提供给我们,所以我们必须做的就是将爆炸音效附加到爆炸GameObject上。

之后,当一颗小行星被摧毁时,爆炸音效就会发挥作用。

另一方面,我想说的是,我真的很喜欢使用Unity的组件系统。

通常你需要手工编写所有的代码,但是在Unity中,它就像拖放一样简单!

 

向子弹添加射击声

对于子弹的声音效果,视频让我们使用现有的脚本来播放我们子弹的声音。

但是,我相信我们可以轻松地将AudioSource附加到我们的子弹预制中,就像我们在爆炸中一样,并在实例化子弹时实现相同的事情。

这是一件很好的事情,所以让我们看看代码:

唯一的补充是高亮部分:

我们使用GetComponent,通过连接到游戏对象的所有组件来搜索AudioSource组件。如果它发现了它,我们就会得到它的一个实例,我们调用Play(),来播放它的声音。

 

添加背景音乐

添加背景音乐很简单。

我们将背景音乐作为一个音频源组件附加到游戏控制器对象上,并将音频源组件设置为循环。

 

计算点数和显示分数

GuiText 对比 UI

在下一节中,我们将创建一个UI来显示游戏的分数。

视频让我们创建了一个空的游戏对象,然后将一个GUIText组件附加到它。

正如你可能回忆的那样,回到roll-a- ball教程中,我们使用了创建画布的UI Gameobjects。那么正确的做法是什么呢?

从我自己的研究来看,GUIText是用来显示文本的旧方法,Canvas系统是实现UI的新方法。

使用Canvas系统的诸多好处之一是,我们可以将自己固定在特定的角度上,就像我们在roll-a- ball教程中看到的那样。如果我们要使用GUIText,我们必须手动移动它们。

 

在脚本中创建我们的分数和调用其他脚本

现在我们已经可以使用GUI了,接下来需要做的就是弄清楚如何获取组件并编辑它。幸运的是,如果你一直跟着教程学习,我们应该知道如何去做!

我们使用GetComponent并获取我们附加到我们的GameObject上的组件!

接下来的问题是:我们应该将游戏对象附加到哪个脚本上?从技术上讲,最简单的东西可能是小行星DestroyByContact 脚本,因为那是我们知道我们得分的时候。

然而,这将带来多种复杂情况:

1)我们会生成多个小行星,所有这些小行星都将具有相同的代码。如果要跟踪总分,每个小行星对象将从0开始,然后当它被破坏时,我们将把我们的文本改为1

2)从我程序员的本能,DestroyByContact脚本不应该是负责保持我们的分数的脚本,我们需要一个跟踪整个游戏状态的管理者,一个控制器!

 

我们很快就会在视频中看到,我们是对的。所有的逻辑都添加到GameController脚本中,正如你在这里看到的:

这里有什么?我们的GameController脚本记录了我们的分数,我们只有一个实例,所以我们不必担心上面讨论的问题。

我们将看到,我们把GUIText附加到脚本上。

我们添加UpdateScore()来初始化我们的文本初始状态。

但是等等!

当我们摧毁小行星时,我们该如何更新分数?我们很快就会看到。

注意,我们有一个public void addScore()函数

一个公共函数是什么意思?这意味着,如果有人访问了我们的脚本组件,他们就可以使用该函数。

看看DestroyByContact的代码,那就是正在做的事情!

回顾一下我们的DestroyByContact代码,我们使用Start()来获取存在的GameController对象的第一个实例。

我们可以先在我们的GameController对象上设置“GameController”这个标签。

我们使用的GameObject类,就像数学库一样,包含可以使用的静态函数,这意味着我们可以随时使用它们。

在本例中:FindWithTag()是一个静态函数,它可以帮助我们搜索带有“GameController”标签的GameObject

FindWithTag()返回GameObject,如果它找到它,否则它返回一个空对象。这就是为什么我们必须首先检查返回的对象是否为空,因为如果我们试图用空对象做任何事情,我们的游戏就会崩溃。

一旦确定我们的GameObject不是空的,我们就做下一件事:获取附加在它的脚本组件。

一旦我们初始化了我们的gameController变量,我们就可以直接调用我们的公有函数AddScore()更新我们的总得分,以摧毁敌人的船。太棒了!

现在每当一艘船爆炸,我们就更新我们的分数!

 

游戏的最后

我们有:

1)玩家太空船

2)敌人的小行星

3)爆炸效果

4)声音效果

5)用户界面

 

在本教程完成之前,只有一件事是要完成的,那就是使游戏结束状态。

为此,我们创建了:

1)另外两个GUIText标签:游戏结束消息和重新启动说明

2)一个布尔值告诉我们游戏是否已经结束

首先看GameController脚本:

 

创建新变量

你能看到的第一件事是我们创建了我们的GUIText对象和布尔值类型变量,让我们检查游戏是否已经结束。

我们在Start()中初始化这些新变量。

创建游戏开始选项

要重新启动游戏,我们必须捕获一个按钮按下输入。为此,我们必须将所有的用户输入代码放在Update函数中。这是唯一持续运行的函数让我们进行这些检查。

在我们的Update()函数中,我们检查是否可以重置,如果可以重置,且用户按下R按钮,我们将重新加载整个应用程序。

我相信我们以后会看到更多关于SceneManager的东西,但是正如你所记得的,我们在Unity中的游戏场景中工作。这意味着,在将来我们可能会有多个游戏场景,我们可以在其中切换。

在本教程中,我们使用应用程序,但这是旧版本。我们现在使用SceneManager

 

在状态上创建游戏

就像我们创建AddScore()一样。我们的GameController不知道游戏什么时候结束。我们必须有一个外部消息来源告诉我们。这就是为什么我们要让GameOver()变成公有函数。

在这个函数中,我们设置了游戏的文本来表示游戏结束,并将我们的gameOver标志设置为true。这并不会立即结束我们的游戏!

如果您注意到产生的敌方代码,即使游戏结束,我们也不会停止创建新的敌人!我们用这个来解决这个问题

 

这样做是我们添加重新启动指令并进入重新启动状态,这意味着我们可以开始检测用户何时在Update()中按R

我们也停止了while循环,所以我们不会永远继续产生小行星。

 

下一部分

很好,我们将GameOver添加到我们的GameController脚本中,但是我们在哪里调用它,

DestroyByContact脚本里!特别是当我们的太空船爆炸。

我们已经有了gameController脚本组件,所以我们需要做的就是调用GameOver

我们去吧!现在我们可以有一个游戏结束状态,重新开始!

 

结论

这是一篇很长的帖子!我正在认真地考虑重新写所有的东西。它需要比实际学习更多的时间,重新观察,然后执行!

然而,积极的一面是,我已经明确地学到了比平时更多的知识,因为我必须明白我写的是什么!

不管怎样,3天前我们几乎没有任何VR的知识,我们现在离做一个VR游戏又近了一步:

1)建立环境

2)创建播放器

3)产生敌人

4)销毁/创建对象

5)创建用户界面

6)检测用户按钮

7)从脚本访问其他对象

阅读原始文章

访问VR挑战100的内容

【版权声明】

原文作者未做权利声明,视为共享知识产权进入公共领域,自动获得授权。

 

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引

标签: