Unity 2020 游戏开发实用指南(一)

原文:zh.annas-archive.org/md5/36713AD44963422C9E116C94116EA8B8

译者:飞龙

协议:CC BY-NC-SA 4.0

前言

我仍然记得我生命中的那一刻,当我害怕告诉我的父母我要学习游戏开发。在那个时候和我所在的地方,大多数父母认为那是一个孩子的愿望,是一个没有未来的职业,但我足够固执,不在乎并追随我的梦想。如今,游戏开发是最大的产业之一,产生的收入甚至超过了电影产业。

当然,追逐我的梦想比我想象的更困难。追求这个特定梦想的人迟早都必须面对这样一个事实,即开发游戏是一项需要在不同领域具有深入知识的艰巨任务。不幸的是,大多数人因为这种困难程度而放弃,但我坚信通过适当的指导和工具,你可以使自己的职业道路更容易跟随。在我的情况下,帮助我降低学习曲线的是学习使用 Unity。

欢迎来到这本关于 Unity 2020 的书。在这里,你将学习如何使用最新的 Unity 功能以最简单的方式创建你的第一个视频游戏。Unity 是一个提供强大但易于使用功能的工具,用来解决游戏开发中最常见的问题,如渲染、动画、物理、声音、特效等。我们将使用所有这些功能来创建一个简单但完整的游戏,学习处理 Unity 所需的所有细微差别。

在本书结束时,你将能够以一种方式使用 Unity,使你能够开始深入研究你感兴趣的游戏开发领域,或者简单地使你能够创建业余游戏,只是为了乐趣。Unity 是一个多功能的工具,既可以用于专业项目,也可以用于业余项目,而且每天都有越来越多的人在使用它。

值得一提的是,Unity 不仅可以用来创建游戏,还可以用来创建任何类型的交互式应用程序,从简单的移动应用到复杂的培训或教育应用(称为严肃游戏),使用最新的技术,如增强现实和虚拟现实。因此,即使我们在这里创建游戏,你正在开始一条可能通向许多可能专业化的学习路径。

这本书适合谁

由于书的结构,具有不同背景的人可以利用整本书或其中的部分。如果你具有基本的面向对象编程(OOP)知识,但以前从未创建过游戏,或者从未在 Unity 中创建过游戏,你会发现本书是游戏开发和 Unity 概念的一个很好的介绍,从基础到高级。即使你是一名经验丰富的 Unity 开发人员,想要学习如何使用其最新功能,你也会发现本书大部分内容都很有用。

另一方面,如果你没有任何编程知识,你也可以从本书中受益,因为大多数章节不需要编程经验来学习。这些章节将为你提供一个强大的基本技能集,你可以从中开始学习如何在 Unity 中编码,当你学会了这些基础的编码知识后,你可以进入本书的面向脚本的章节。

本书涵盖的内容

第一章《从零开始设计游戏》是我们在打开 Unity 之前讨论本书中要创建的游戏的细节的地方。

第二章《设置 Unity》是你将学习如何在计算机上安装和设置 Unity 的地方,也是你将创建你的第一个项目的地方。

第三章《与场景和游戏对象一起工作》是我们将学习有关场景和游戏对象的概念的地方,这些是 Unity 用来描述你的游戏世界由什么组成的一部分。

第四章,使用地形和 ProBuilder 进行灰盒设计,是我们将创建我们的第一个级别布局,并使用 Unity 的地形和 ProBuilder 功能进行原型设计。

第五章,导入和集成资产,介绍了图形。由于 Unity 不是用来创建图形的工具,而是用来显示它们的,我们将学习如何通过将图形导入 Unity 来改进我们场景的艺术。

第六章,使用 URP 和 Shader Graph 的材质和效果,我们将学习如何使用最新的 Unity 渲染系统(Universal Render Pipeline),以及如何使用 Shader Graph 功能创建效果。

第七章,使用粒子系统和 VFX 图创建视觉效果,是您将学习如何使用两个主要的 Unity 工具来创建视觉效果,比如水和火:粒子系统和 VFX 图。

第八章,使用通用渲染管线进行照明,涵盖了照明。照明是一个足够大的概念,有自己的章节。在这里,我们将加深对通用渲染管线的了解,特别是看看它的照明能力。

第九章,使用后期处理进行全屏效果,深入研究了效果和后期处理。为了获得大多数现代游戏所具有的电影效果,我们将学习如何在我们场景图形的顶部添加一层效果,使用通用渲染管线的后期处理功能。

第十章,声音和音乐集成,涉及一个经常被忽视的领域:声音。在大多数初学者开发者看来被低估了,这里我们将学习如何正确地将声音和音乐添加到我们的游戏中,并考虑其对性能的影响。

第十一章,用户界面设计,探讨了用户界面(UI)的使用。在所有基于图形的向用户传达信息的方式中,使用 UI 是最直接的。我们将学习如何使用 Unity UI 系统以文本、图像和生命条的形式显示信息。

第十二章,使用 Animator、Cinemachine 和 Timeline 创建动画,让我们摆脱简单的静态场景。在这一章中,我们将开始使用动画移动角色,并使用最新的 Unity 功能创建过场动画。

第十三章,使用 C#进行 Unity 脚本编程的介绍,是本书的第一个编程章节。我们将学习如何按照 Unity 的方式使用 C#创建我们的第一个脚本。

第十四章,实现移动和生成,是我们将学习如何编写对象的移动以及如何生成它们。从现在开始,假设具有一般的编程知识。

第十五章,物理碰撞和生命系统,是您将学习如何配置对象的物理设置以侦测它们何时发生碰撞并对碰撞做出反应。为了将其付诸实践,我们将创建一个生命系统。

第十六章,胜利和失败条件,是我们将检测游戏何时应该结束的地方,当玩家赢得游戏或输掉游戏时。

第十七章UI、声音和图形脚本,我们将制作先前创建的 UI,以显示游戏的相关和当前信息,如玩家的健康和得分。此外,我们将研究在必要时播放声音以及使用视觉效果来反映玩家的行为。

第十八章实现游戏 AI 以构建敌人,我们将使用 Unity 的几个功能创建基本的 AI,以在游戏中创建具有挑战性的敌人。

第十九章场景性能优化,探讨了性能问题。使我们的游戏表现良好并不容易,但如果我们想发布游戏,这当然是必须的。在这里,我们将学习如何分析游戏的性能并解决最常见的性能问题。

第二十章构建项目,我们将学习如何将 Unity 项目转换为可执行格式,以便将其分发给其他人并在没有安装 Unity 的情况下运行。

第二十一章最后的修饰,我们将简要讨论在完成本书后如何推进游戏的开发,讨论诸如如何迭代和发布游戏等主题。

第二十二章Unity 中的增强现实,为您介绍了增强现实AR)。在这个额外的章节中,我们将学习如何使用 Unity 的 AR Foundation 包创建 AR 应用程序,这是最近发布的一种使用 Unity 创建 AR 应用程序的方式。

为了充分利用本书

在本书的各章中,您将开发一个完整的项目,虽然您可以只阅读各章,但我强烈建议您在阅读本书的过程中练习项目中的所有步骤,以获得适当学习这里所讨论概念所需的经验。各章的设计使您可以根据自己的喜好定制游戏,但请考虑不要偏离主要思想。

项目文件按章节分成文件夹,并以累积方式设计,每个文件夹只包含该章引入的新文件或与以前章节不同的文件。这意味着,例如,如果一个文件自第一章以来没有改变,您将在第二章以后的文件夹中找不到它。您可以在每个章节文件夹中打开场景文件,以查看游戏在该章节结束时应该是什么样子。这样可以让您看到每章节中发生的变化,并且意味着您可以轻松识别必要的变化。例如,如果由于某种原因,您无法完成第三章,您可以直接从已解决的第四章文件夹中继续。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们建议您自己输入代码,或者通过 GitHub 存储库访问代码(链接在下一节中提供)。这样做将有助于避免与复制和粘贴代码相关的任何潜在错误。

请注意,本书及其示例是使用 Unity 2020.1.0f1 编写的,这是目前可用的最新版本。这是 Unity 2020 的第一个版本,虽然可能有更新版本,但请考虑,如果您使用它们,书中所示的截图或步骤可能会有轻微差异,但并不难解决。

下载示例代码文件

您可以从您的帐户在www.packt.com下载本书的示例代码文件。如果您在其他地方购买了本书,您可以访问www.packtpub.com/support并注册,以便直接通过电子邮件接收文件。

您可以按照以下步骤下载代码文件:

  1. 登录或注册,请访问www.packt.com

  2. 选择支持选项卡。

  3. 点击代码下载

  4. 搜索框中输入书名,并按照屏幕上的说明操作。

下载文件后,请确保使用最新版本的解压缩或提取文件夹:

  • Windows 的 WinRAR/7-Zip

  • Mac 的 Zipeg/iZip/UnRarX

  • Linux 的 7-Zip/PeaZip

该书的代码包也托管在 GitHub 上,网址为github.com/PacktPublishing/Hands-On-Unity-2020-Game-Development。如果代码有更新,将会在现有的 GitHub 存储库中更新。

我们还有其他代码包,来自我们丰富的书籍和视频目录,可在 https://github.com/PacktPublishing/ 上找到。看看吧!

下载彩色图片

我们还提供了一个 PDF 文件,其中包含本书中使用的屏幕截图/图表的彩色图片。您可以在这里下载:

static.packt-cdn.com/downloads/9781838642006_ColorImages.pdf

使用的约定

本书中使用了许多文本约定。

文本中的代码:指示文本中的代码词、数据库表名、文件夹名、文件名、文件扩展名、路径名、虚拟 URL、用户输入和 Twitter 句柄。这是一个例子:“将其着色器设置为Universal Render Pipeline/Particles/Unlit。”

粗体:表示一个新术语、重要单词或您在屏幕上看到的单词。例如,菜单或对话框中的单词会以这种方式出现在文本中。这是一个例子:“创建一个新的空 GameObject(使用GameObject | Create Empty)。”

提示或重要说明

像这样出现。

第一章:从零开始设计游戏

欢迎来到本书的第一章!我相信你和我一样对使用 Unity 进行游戏开发的惊人旅程充满期待。我们将分四部分来接触游戏开发。首先,我们将讨论游戏开发的基础知识,涉及如何在编码之前设计游戏等主题,然后我们将使用 Unity 原型制作一个简单的第一关。然后,我们将深入图形学,找出一个好游戏的外观和感觉。之后,我们将学习如何通过脚本使一切运动起来;最后,我们将看到你如何完成并发布你的游戏。在阅读各章节时,你将把每个概念应用到一个完整的游戏项目中,因此你将以一个完全功能的射击游戏结束本书。

在这一章中,我们将设计我们的游戏《超级射手》。这个阶段被称为前期制作,我们将创建一个开发计划。我们的游戏设计将包括我们想要在游戏中拥有的所有功能:玩家角色、非玩家角色、游戏资产、动画等等。我们将使用屏幕模拟以及叙述来记录我们游戏的设计。我们将在这个过程中讨论有关使用 Unity 开发我们的游戏所需的所有设计工作的相关概念。我们将讨论在整个本章中我们将要做的所有设计工作所需的文档。

具体来说,我们将在本章中研究以下概念:

  • 游戏概念

  • 游戏角色

  • 游戏玩法

  • 难度平衡

  • 文档

游戏概念

为什么不直接开始开发我们的游戏而不是先设计它呢?这个问题源自于开发游戏的兴奋,特别是使用 Unity 游戏引擎。所有的游戏都始于一个想法。这个想法被转化为设计,而这个设计是开发和最终游戏的基础。

游戏的设计就像房子的蓝图。你不会考虑在没有蓝图的情况下建造房子,同样,开发游戏而不先设计它也是一个同样糟糕的主意。这样做的原因是为了节省时间和挫折。对于更大的项目,浪费的时间也意味着不必要的资金支出。

想象一下,你雇佣了一个由 12 名开发人员、动画师和艺术家组成的项目团队。如果你分享了你的游戏想法,他们会有足够的信息吗?他们会做出很棒的东西,但没有一个统一的游戏组件吗?我们在游戏设计中所做的一切就是在一开始尽可能多地记录,以便开发过程是有目的的。毫无疑问,在开发过程中,你将不断修改你的游戏设计,因此拥有一个坚实的起点对你的成功至关重要。

我们的游戏设计将作为我们游戏外观的基础,玩家的目标是什么,游戏玩法是什么,以及支持用户操作、动画、音频、人工智能和胜利条件。这是需要考虑的很多内容,也强调了将游戏想法转化为游戏设计的重要性。

在整本书中,我们将涵盖一系列组件。然而,在本节中,我们将涵盖以下列表中出现的组件:

  • 游戏想法

  • 输入控制

  • 胜利和失败

所以,让我们更详细地看看每个组件。

游戏想法

我们《超级射手》游戏的基本概念是,它将是一个 3D 游戏,以未来英雄士兵为玩家角色。角色必须与敌方士兵作战。这些敌人打算摧毁我们英雄的基地,以及任何阻挡他们的人,包括我们的英雄。他将有一定数量的子弹需要跟踪。

既然我们已经大致知道游戏将会是什么样子,让我们来谈谈玩家将如何控制角色。

输入控制

考虑玩家如何与我们的游戏互动是很重要的。玩家将使用标准的控制方式来控制我们的英雄。玩家期望游戏中实施用户控制的行业规范。因此,我们默认的用户输入控制组合,如下截图所示,将包括键盘和鼠标:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1.1 - 控制方案

我们将配置和编程我们的游戏,以便键盘的用户输入与下表中显示的键和动作配对相匹配:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1.2 - 键映射

鼠标也将是用户输入的重要来源。我们将使用鼠标实现两个组件,如下表所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1.3 - 鼠标映射

左鼠标按钮将是我们的动作按钮。我们需要确保只有当玩家剩下一个或多个子弹时才会射击子弹。

这就是我们处理输入的方式,但有时我们需要结束游戏会话!让我们谈谈玩家如何获胜和失败。

获胜和失败

我们的获胜条件是当所有敌人波都被消灭时。玩家可以输掉游戏的两种不同方式。第一个失败条件是当基地生命值变为0时。第二个失败条件是如果英雄的生命值变为0

通过这个简短的描述,你可以知道有几件事情需要跟踪,包括以下内容:

  • 剩余波数

  • 我们基地的生命值

  • 我们英雄的生命值

现在,我们已经定义了所谓的游戏“核心循环”(开始一个关卡,玩它,赢/输它,然后重复)。让我们深入探讨具体细节,从我们的角色开始。

游戏角色

我们的游戏将包含几个对象,但只有两种游戏角色。第一个游戏角色是我们的英雄,将由玩家控制。第二种游戏角色是敌人。他们是由人工智能控制的非玩家角色。让我们更仔细地看看这两个角色。

英雄

玩家将扮演我们游戏的主角英雄。这是一个我们将导入并在游戏中使用的角色。那么,我们的英雄玩家角色能做什么呢?我们已经知道我们将能够使用键盘和鼠标输入的组合在游戏环境中移动他们。我们也知道左鼠标按钮 - 我们的动作按钮 - 会让他射击子弹。

重要提示:

因为英雄是由人类玩家控制,所以被称为玩家角色。

我们将为英雄实现以下动画:

  • 空闲:当角色没有被玩家移动时,将播放此动画。

  • 奔跑:当角色被玩家移动时,将播放此动画。

  • 射击:这是一个会让英雄射击子弹的动画。

这是我们的玩家。现在,让我们讨论我们的敌人角色。

敌人

我们游戏的反派将是敌人士兵。我们将控制他们在游戏中的数量和位置。我们还将通过人工智能控制他们的行为。敌人将直奔基地,一旦到达那里,他们将开始破坏它。我们将确定我们的基地被完全摧毁需要多长时间。

信息框:

因为敌人是由人工智能控制而不是人类玩家,所以被称为非玩家角色。

我们将为敌人士兵实现以下动画:

  • 奔跑:当敌人看到英雄时,他们将向英雄奔跑,并在靠近玩家足够近时停下来开始攻击。

  • 攻击:当敌人靠近攻击基地或玩家时,将播放此动画。

  • 死亡:当敌人被玩家击败时,将播放此动画。

我们需要仔细的规划和脚本编写来创建所需的敌人行为。敌人的数量和位置是我们需要做出的决定。

这定义了我们角色的细节。现在,让我们讨论游戏将如何进行,看看具体的细节。

游戏玩法

游戏将从玩家位于游戏世界中心开始。由玩家控制的英雄需要保卫基地免受敌人的攻击。为了击退敌人,英雄将拥有一定数量的子弹。目标是在基地被完全摧毁之前击败所有的敌人。

让我们看看我们将如何实现所有这些。本节涵盖了以下游戏组件:

  • 游戏世界布局

  • 起始条件

  • 结束条件

  • 积分系统

  • 头顶显示HUD

我们将涵盖每个前面的组件,并讨论它们如何改变游戏体验。让我们从游戏世界的设计开始谈起。

游戏世界布局

我们将创建我们的基地环境,其中包括大型金属地板砖、墙壁、敌人生成的门,以及屏幕底部的基地建筑,敌人需要到达并开始攻击它。

这是我们游戏世界的形状的模拟:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1.4 - 基地布局

在前面的模拟中有四个基本的事物,列举如下:

  • :无法穿透的屏障,防止玩家走出游戏区域。

  • :与墙壁一样坚固,也将作为敌人的生成位置。敌人将在它们的后面生成,并可以穿过它们进入我们的基地区域。

  • 玩家起始:英雄的起始位置。

  • 基地建设:我们的基地。敌人必须足够接近才能攻击它。

随着我们基地级别设计的完成,让我们讨论玩家如何以温和的方式进入这个世界。

起始条件

当我们的游戏首次启动时,我们将设置几个起始条件。以下是这些条件的列表:

  • 敌人生成点(门)的数量和位置

  • 英雄持有的子弹数量

  • 基地的位置

让我们看看每个这些起始条件:

  • 第一个起始条件是敌人的生成位置。正如您在我们之前的模拟中看到的,游戏中将有几个可能的生成点(门)。我们将编写一个脚本,以便每次在随机位置生成敌人的波数。每一波都会增加敌人的数量,增加难度。

  • 玩家持有的子弹数量必须经过仔细考虑。它需要足够大,以在敌人耗尽之前击败敌人。

  • 我们的第三个和最后一个起始条件是基地的位置。正如您从前面的截图中看到的,它位于门的对面 - 因此,敌人必须穿过它们之间的整个空间,给玩家一个攻击他们的机会。

我们已经定义了敌人生成规则以及玩家如何玩游戏。现在,让我们谈谈游戏将如何结束,看看具体的实现方式。

结束条件

到目前为止,我们已经确定了游戏中要跟踪的几个组件。让我们记住它们 - 它们如下:

  • 剩余波数

  • 基地健康

  • 玩家健康

根据我们之前对游戏结束条件的决定,我们可以应用以下数学检查来确定游戏是否结束以及结果是什么。每个游戏结束条件都列在下表中,以及结果:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1.5 - 游戏结束条件

为了实现这三个游戏结束条件,我们知道我们必须跟踪波数、玩家健康和基地健康。这是必须的。

现在我们有了一个完整的游戏,让我们考虑如何通过实现一个经典的积分系统使其更有价值。

积分系统

由于我们正在跟踪涉及数字的关键信息,这使得我们可以轻松实现一个积分系统。例如,每次消灭一个敌人,我们可以给玩家 50 分,或者每次敌人损害基地时我们也可以扣分。在我们的情况下,我们将只在敌人被杀时给分,但如果您愿意,可以随意扩展这个领域。

现在,我们有几个玩家需要了解的系统,但是目前玩家没有任何方法可以对其做出知情决策。因此,让我们看看如何使用 HUD 来改进。

HUD

我们决定在游戏过程中跟踪信息,这些信息不仅在计算得分和游戏结束时有价值。玩家会希望看到这些信息,因为它往往会提供动力,并增加游戏的乐趣。因此,我们将为玩家创建一个 HUD,并动态更新游戏中的数据。

信息框:

HUD 是屏幕上始终存在的信息视觉层。

这是我们超级射手游戏中 HUD 的模拟图:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1.6 – UI 布局

正如您所看到的,我们的 HUD 有几个组件,如下:

  • 英雄生命值:经典的生命值条,让我们可以直观地看到剩余的生命值。我们选择条形图而不是数字,因为在激烈战斗中更容易看到,而不是读取数字。

  • 英雄头像:生命值条旁边的图像,只是为了展示我们英雄的面孔。

  • 得分:我们已经获得的分数。

  • 子弹:剩余的子弹数量。玩家必须经常检查这个数字,以避免用尽子弹。

  • 剩余波次/敌人:关于当前波次和游戏状态的信息,只是让玩家知道游戏何时结束,在此过程中给他们施加一些压力。

  • 基地生命值:另一个重要的信息。足够大,让玩家注意到基地正在受到攻击,并在这种情况下采取行动。

最后,我们有一个完全成熟的游戏,有很多关于它将如何行为的规则和规范,我们现在可以开始创建我们的游戏。然而,有一个好的实践是:平衡游戏永远不会太早。

难度平衡

确定游戏难度时需要考虑很多因素。如果太难,玩家会失去兴趣,如果游戏太容易,可能不会吸引目标受众。一些游戏包括供用户选择的难度级别。其他游戏有多个级别,每个级别难度逐渐增加。为了实现我们期望的难度平衡,我们必须应对几个问题。

在本节中,我们首先将看一些与难度平衡相关的问题,然后是我们的实施计划。

难度平衡问题

我们需要在游戏设计中考虑很多关于我们游戏的问题。回顾本节中的问题将帮助我们了解即使是像我们这样简单的游戏也必须应对的问题,以实现期望的难度平衡。

以下是第一组问题,与我们游戏中难度的整体实施有关:

  • 我们是否应该有玩家可选择的不同难度级别?

  • 每个难度级别会有什么具体不同?

  • 我们是否应该有多个游戏级别,每个级别难度增加?

  • 每个游戏级别会有什么具体不同?

考虑以下关于我们游戏中敌人的问题:

  • 每个波次应该生成多少敌人?

  • 敌人应在多远的距离内意识到英雄?

  • 敌人每次攻击应对玩家造成多少伤害?

  • 敌人可以忍受多少伤害才会死亡?

以下列出的下一组问题涉及我们的可玩角色,英雄:

  • 角色应该有多少生命?

  • 角色应该从单个敌人的攻击中受到多少伤害?

  • 角色应该能够超越敌人吗?

我们还需要考虑基地和子弹在我们的游戏中。以下是我们将在游戏中实施的这些游戏资产的一些问题。对于基地,问题如下:

  • 敌人摧毁基地需要多少次攻击?

  • 一波中产生的敌人的理想最大数量是多少?

  • 门和基地应该在游戏环境中的哪里?

现在,让我们讨论子弹的情况下的问题,如下所示:

  • 玩家应该以什么速度用尽子弹?

  • 玩家可以拥有的子弹的最大数量是多少?

  • 子弹会对敌人造成多少伤害?

正如你所看到的,我们需要回答几个问题作为我们设计的一部分。一些问题可能看起来多余,因为它们涉及游戏中的多个组件。现在,让我们回答其中一些。

实施计划

根据上一节中提出的问题,我们必须想出一些答案。所以,让我们在这里做到这一点。我们的第一组决策集中在整体游戏概念上,如下所示:

  • 实施一个游戏级别。

  • 为用户提供三种游戏难度设置:简单普通困难

现在我们决定创建三个游戏级别,我们必须确定它们将如何不同。这可以通过使用矩阵轻松管理。当我们填写矩阵时,我们将能够记录大多数先前列出的问题的答案。这就是我们将称之为难度实施矩阵的东西。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1.7 - 每个级别的难度通过

还将有一组决策,不会根据用户选择的难度级别而改变。以下是这些决策的列表:

  • 敌人的攻击性不会改变。我们将对它们进行脚本编写,以便如果它们意识到英雄,它们将攻击他。

  • 我们将为敌人建立一个相当小的视野范围,这样英雄可以轻松地溜过它们,也许更重要的是,超过它们。

  • 重生将在游戏模型中先前确定的生成点之间随机进行。

重要的是要考虑到这是第一次平衡调整,我们肯定会根据我们进行游戏实施时进行的测试进行更改。

现在,我们可以说游戏设计已经完成了,还是可以吗?实际上,游戏设计永远不会结束;随着游戏的开发,它将不断发展,但让我们把这个留到以后。现在,让我们谈谈如何用文档与团队中的每个人沟通我们伟大的想法。

文档

现在我们已经涵盖了游戏的所有主要方面,重要的是要准备好与他人分享。通过这本书,你可能会独自工作,但在现实生产中,你可能会与他人合作,因此分享你的愿景是你需要获得的关键技能,以创造成功的游戏。你不仅会与队友分享你的愿景,还会与希望投资你的游戏项目的潜在投资者分享。在本节中,我们将提供关于如何将游戏信息正确格式化为可理解文件的建议。

游戏设计文件(GDD)

这个文件基本上是你的游戏圣经。它包含了游戏的所有方面的分解,每个方面都有关于不同游戏系统应该如何工作的详细解释。在这里,你将把我们之前在实施计划中回答的问题和答案放在一起,并深入研究它们。记住,你脑海中有一个想法,确保其他人理解那个想法是复杂的,所以不要低估这一重要任务。

也许你正在独自制作一款游戏,并且说你不需要 GDD,因为所有的想法都可以在你的脑海中得到体现,对于非常小的游戏来说可能是真的,但任何规模的游戏和团队都可以从 GDD 中受益。它将作为你的笔记本,记录下你自己的想法并阅读它们。这很重要,因为在你的脑海中一切都是有意义的,但一旦你阅读自己的想法并审查它们,你会发现很多盲点可以很容易地修复,而不是在编写整个游戏时才发现它们。

让我们开始谈论 GDD 的结构可以是什么样的。

GDD 格式

遗憾的是,没有一种标准或独特的创建 GDD 的方式。每家公司和团队都有自己的做法,不仅在创建它时使用的工具方面,还有文件的内容。这在很大程度上取决于团队的规模(或团队)、游戏类型和公司背后的一般文化。事实上,一些公司实际上认为没有必要创建 GDD。

开始创建它们的一个好主意是查看几款游戏的已发布 GDD。有很多这样的游戏,包括大型知名游戏(如《毁灭战士》)。它们大多是 Word 文档,其中有解释游戏系统(如武器、库存等)的部分,以及所有角色的列表,而有些可能只是一个列出游戏不同部分的事实的项目列表。之后,你可以开始尝试不同的 GDD 格式,以适应你的项目和团队。

一旦你决定了一个好的格式,你必须实际决定你将如何写这个格式,除了使用纸和笔,一个更好的主意是利用所有那些出色的数字工具。让我们看看其中一些。

GDD 创建工具

在审查现有的 GDD 之后,下一步是选择一个合适的工具来编写它。你需要考虑的第一件事是,GDD 会经常发生很多变化。在创建游戏的过程中,你将验证或放弃你在 GDD 中写的想法,所以使用一个动态工具是个好主意。这可以通过你熟悉的任何文本处理器来实现,但你还需要解决其他问题,也许文本处理器不够用。

你的 GDD 会很大,我的意思是,非常大,即使对于简单的游戏来说也是如此,所以它会有很多部分,你会发现整个部分都会引用其他部分,生成一个大的链接网络连接文档的几个部分。在这种情况下,使用任何一种维基而不是文本处理器来管理这一点是个好主意,维基是极其有用的工具,我强烈建议在这些情况下使用。它们允许你将整个 GDD 分解为可以轻松编辑和链接到其他文章的文章,而且许多维基还允许你协作编辑文章。还有其他附加功能,比如评论,允许在 GDD 内部对一个功能进行整个对话,并记录下来以供将来参考。与 GDD 相关的维基百科页面可以在以下截图中看到:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1.8 - 维基百科网站

此外,你还可以使用其他工具,比如 Google Drive,它允许你混合不同类型的文档 - 从常规文本文档到动态幻灯片 - 来创建演示文稿,用简单而强大的媒体传达复杂的方面。此外,Google Drive 还有许多出色的协作工具,可以改善多人共同参与 GDD 的工作方式。

我们描述的所有工具都是通用的解决方案,用于撰写一般文件,它们可以像魅力一样工作,但也有其他专门为游戏设计的工具。

现在,让我们开始写我们的 GDD。我知道我说没有标准格式,但至少让我们看看每个 GDD 应该有什么,从电梯演讲开始。

电梯演讲

想象一下,你在一栋大楼里乘坐电梯,下一层,一个重要的游戏投资者刚好进来了。他们按了十楼的按钮,所以你有八层的时间来说服他们把钱投入你的口袋,帮助你创造游戏。我知道这是一个不太可能的情况,但在现实生活中,当你站在一个圆桌前面的投资者面前时,你没有太多时间说服他们。记住,在你身后可能有成千上万的开发者想要做同样的事情,所以你必须快速而直接,这就是为什么拥有一个好的电梯推销如此重要。

电梯推销可能是你在 GDD 中找到的第一句话,也是最重要的一句。它需要用不超过两行来描述你的游戏,并说服阅读 GDD 的人你的游戏是一个好主意——你需要让他们立刻想要玩你的游戏。是的——听起来非常雄心勃勃,而且确实如此,但这可以让你脱颖而出,与众多想为他们的游戏获得资金的开发者区分开来。

再次强调,没有标准的公式可以创造成功的电梯推销(如果有这样的东西,我们都会变得富有),但以下是一些需要考虑的建议:

  • 你必须在不超过 10 秒的时间内做出你的推销。再长一点,你就会失去你试图说服的人的兴趣。

  • 你必须对自己的想法有信心;没有人会投资于你自己都不确定的游戏是否是下一个大作。

  • 不要使用任何技术性词汇(我在看你,程序员)。

  • 包括你的游戏与所有其他游戏的区别。

  • 反复修改,直到你能说服身边的任何人来玩这个游戏,试着找一个最诚实的人来测试——一个不会介意把你的想法击得粉碎的人(如果你的想法真的值得的话)。

  • 反复练习,站在镜子前,直到你能够清晰、明确地一次说出来。

以下是一些电梯推销的例子:

  • 想象一下用你的手臂和力量屠杀巨大的希腊神祗,直到你成为奥林匹斯之王。你将在[在这里插入一个完全不存在的游戏名称]中感受到那种力量。

  • 文明已经崩溃。可怕的感染让人们变成了僵尸。你拥有唯一的解药,必须穿越整个国家去交付它,否则人类将崩溃。

好吧——现在这些推销可能不是很原创,但几年前它们是的。想象一下那时这些推销的力量;你必须找到类似的东西。我不是说这很容易,但看看只有两行可以成为惊人体验的开始,所以首先专注于写下这两行,然后再写游戏的其余部分。

现在你已经吸引了投资者的注意,是时候向他们展示所有的游戏系统和一些细节来进一步激发他们的热情,好吧,现在不是时候。你刚刚吸引了他们的注意,你还没有说服他们。现在是时候开始谈谈你的游戏,一个高概念是一个很好的方式。

一个高概念

一个高概念是一系列陈述,进一步简洁地描述你的游戏,即使你不是在说服投资者,这些陈述也会概述你的游戏将如何定义。

一个好的高概念可以包括以下部分:

  • 电梯推销:正如我们在前一节中所解释的。

  • 类型:也许您正在创造以前从未见过的新东西,但它可能会受到其他几款游戏的启发。在这里,您将指定您的想法基于哪种类型的游戏,以便文档的读者可以开始想象游戏的玩法。稍后,您将指定区别,但最好先提出一个众所周知的想法,以便开始构建读者的概念。此外,您还可以在此处指定玩家在游戏中的视角和设置,例如:顶部中世纪 Roguelike 角色扮演游戏(RPG)

  • 平台和人口统计:您需要非常清楚地知道谁会玩您的游戏。为北美成年人创建游戏与为中国青少年创建游戏或为那些想在回家的路上或公交车上分散几分钟注意力的商务人士创建游戏并不相同。这些人群会希望不同的体验,不同挑战的水平和游戏时长。他们甚至会使用不同的设备来玩游戏。考虑到这一点,将有助于您找到最适合目标受众的游戏机制和平衡。通常人们会说他们正在为自己创建游戏,但请记住您不会购买那款游戏,因此在创建游戏时也要考虑您的钱包,例如:休闲手机平台玩家

  • 特点:列出您的游戏将具有的不超过三到五个特点。列出您将从所选择的游戏类型中使用的特点,例如:您将用各种武器击败敌人的波浪。您将升级您的飞船以提高其属性

  • 独特卖点(USP):这与特点列表类似,但在这里,您将包括区分您的游戏与其他游戏的特点(不超过三到五个),例如:您可以使用跑酷风格的动作穿越场景。您可以使用掠夺的材料制作全新的武器。想想这些特点在多年前是多么独特。

再次强调,没有理想的高概念。也许您会发现游戏的其他方面可以在此处突出并添加到文档中,但请尽量将所有内容放在一页上。

现在我们已经讨论了每个 GDD应该具备的内容,让我们谈谈 GDD可能具备的内容。

创建 GDD 的提示

现在,是时候定义整个游戏了。我们说 GDD 没有标准格式,但至少在创建时可以考虑几种良好的做法。以下列表突出了其中一些:

  • 可读性:您的 GDD 必须准备好供任何人阅读,包括没有游戏开发知识的人。不要使用任何技术术语(猜猜我现在在看谁),并尽量保持简单。测试您的 GDD 可读性的一个好方法是将其交给您的祖母或任何您认为与游戏毫不相干的人,看看他们是否能够阅读。

  • 背景和介绍:在开始描述游戏机制之前,让读者置身于游戏中。描述世界、玩家角色、他们的背景故事、动机以及玩家需要努力解决的主要问题。让 GDD 的读者对游戏的背景感兴趣,并希望继续阅读,看看他们将如何玩游戏并应对游戏中玩家将面临的所有任务。

  • 游戏玩法部分:这些部分将游戏分解为相互关联的几个系统和子系统。一些示例可以是库存、任务、制作、战斗、移动、商店等等。您将需要非常具体地说明这些系统的每个方面,因为请记住,这份文件将被团队用来制作游戏的代码和资产。我们在本章的前几节中进行的所有先前分析都将在这里,并将进一步解释和分析。

  • 内容部分:你还会想创建内容部分,比如我们之前设计的部分。这些可以是——但不限于——角色、故事、世界、关卡、美学、艺术资产、声音和音乐资产、经济和输入。

  • 分享你的想法:在将你的想法永恒化在 GDD 上并让每个人开始制作它们之前,讨论不同的 GDD 部分然后再标记它们为完成。与你的团队、互联网上的人、朋友讨论——每个人都可以给你有价值的反馈关于你的想法。我很确定你在想你的想法会被互联网上的某个随机人偷走然后在你之前发布相同的游戏——这种情况可能会发生——但我并不是说分享整个 GDD,只是一些你对某些实施细节不确定的细节。

  • 保持控制:团队中的每个人都是游戏设计师——有些人比其他人更多。每个人都会有自己的想法和他们会做不同的事情。倾听他们——这样做会很有用,但记住你是负责人,你将有最后的决定权。你需要开放,但设定一些限制,不要偏离你最初的想法和概念。防止著名的功能蔓延:知道什么是足够。再次强调,这并不是一项容易的任务——你会以艰难的方式学到这一点,相信我,但当发生这种情况时,请记住这一点:我告诉过你!

  • 游戏会改变:我已经说过了,但我想尽可能强调这一点。游戏会因为你在创建过程中发现的许多原因而发生很大的变化。你可能会发现X机制并不那么有趣,你创造了更好的处理Y系统的方法,你认为值得花时间改变已经存在的游戏部分,因为测试表明玩家不理解如何使用你游戏中全新的关键功能,等等。要对变化持开放态度,并调整你的游戏想法。如果你以正确的方式做到这一点,你的游戏不会像你最初想象的那样,但会是它的更好版本。

  • 图形:使用图形、图表等。尽量避免大段文字。记住一张图片胜过千言万语。你正在沟通,没有人想要花费宝贵的时间来理解你想要表达的内容。提高你的视觉沟通能力,你将拥有一个专注的团队。

  • 纸上原型:在将想法写入 GDD 之前,你可以在纸上测试一些想法。即使你的游戏是一个狂热的“打击他们”,你也可以让小纸人物在桌子上移动,看看他们如何攻击玩家,以及他们将会有哪些移动模式。做一些数学来看看完美的时间、伤害和生命值等。

  • 定期原型:当你的游戏正在开发时,GDD 将会根据玩家的反馈不断变化。你必须测试你的游戏,即使它还没有完成,并尽早从玩家那里得到反馈。当然,他们会告诉你很多你已经知道的事情,但他们会看到你没有看到的很多问题,因为你每天都在创作和玩你的游戏。他们有第一次玩游戏的优势,这是一个真正的改变。

游戏设计和 GDD 的创建是一个复杂的主题,可以在几章中探讨,但有很多书籍正是这样做的,游戏设计并不是本书的主要内容。

在这之后,我们可以开始创建我们的 GDD,并记住:你需要找出对你最有效的格式是什么。

总结

在这一章中,我们完全设计了我们的超级射手游戏,并计划利用我们的设计来推动我们的开发工作。我们的游戏设计包括功能、玩家角色、非玩家角色、游戏资产、动画等等。我们使用屏幕模拟来帮助记录我们游戏的设计。此外,我们计划了游戏的难度平衡,以确保游戏根据用户选择具有适当的难度。我们讨论了什么是 GDD,我们如何创建它,以及它和游戏设计在游戏制作过程中会发生什么变化。

请记住,这很重要,因为您希望在编写游戏代码之前回答所有可能的问题。如果您不这样做,您将不得不一遍又一遍地重新编写游戏的部分,以解决每一个意想不到的问题。您无法预防所有可能的复杂情况,但至少通过这种分析,可以解决大部分问题。

在下一章中,您将学习如何开始使用 Unity。您将了解为什么 Unity 是一个很好的选择来开始创建游戏。您将创建您的第一个游戏项目,并分析它是如何组成的。

第二章:设置 Unity

在本章中,我们将学习为什么 Unity 是一个很好的游戏引擎入门工具。开始游戏开发职业有很多种方式,因此选择合适的工具是迈出的重要第一步。然后,我们将看到如何安装 Unity 并使用 Unity Hub 创建项目,这是一个管理不同 Unity 安装和项目的工具,帮助我们处理大量项目。

具体来说,在本章中我们将研究以下概念:

  • 为什么要使用 Unity 这样的游戏引擎?

  • 安装 Unity

  • 创建项目

让我们首先讨论为什么选择 Unity 来开始你的游戏开发职业。

为什么要使用 Unity 这样的游戏引擎?

当你想创建一个游戏时,有几种方法可以选择,每种方法都有其利弊。那么,为什么选择 Unity 呢?在本节中,我们将讨论这些原因,概述先前和当前行业状态,并具体看到以下概念:

  • 过去和现在的行业洞察

  • 游戏引擎

  • Unity 的优势

过去和现在的行业洞察

在开始阶段,用户们在设备资源有限但游戏设计简单的情况下挣扎。随着行业的发展,硬件变得更加强大,游戏也比以前更加复杂。一个大型 AAA 游戏标题需要近 200 名开发人员,负责游戏的不同领域。这些角色中的每一个都需要多年的经验,使得游戏成为一项昂贵且风险高的任务:你永远不知道一个游戏是成功还是浪费了大量资金。因此,一个人很难制作整个游戏。

重要提示:

AAA 游戏是由许多在大公司工作的人创建的,通常成本数百万美元。还有 AA 游戏,这意味着团队规模和预算的差异。

过去,程序员需要学习如何使用许多工具来解决不同的游戏开发问题。一些工具停止了来自其创建者的支持,留下了未解决的错误和功能。因此,大公司开始雇佣高技能的开发人员来创建所有这些工具,结果就是所谓的游戏引擎。让我们来回顾一下这是什么。

游戏引擎

游戏引擎是一组不同的软件,解决游戏开发中的问题,如音频、图形和物理问题,但它们被设计为一起工作,都遵循相同的理念。这很重要,因为每个团队和公司都有自己的工作方式。从零开始创建游戏引擎是一项艰巨的任务,只有少数大公司能够做到这一点。公司创建的游戏引擎通常是私有的,所以只有公司被允许使用它们。一些公司出售他们的引擎,但成本太高。但几年前出现了另一种获取游戏引擎的方式。

你可能听说过由 1 至 10 名开发人员创建的独立游戏,但是这样一个小团队如何创建游戏呢?答案是通用游戏引擎。这些游戏引擎就像公司创建的那些一样,但它们被设计为每个游戏的良好基础,并提供一个准备好供任何游戏开发者使用的工具集。这些引擎创造了一整代的热衷开发者,他们现在能够比以前更容易地开发自己的游戏。过去有很多游戏引擎公司,但只有少数公司今天还在生存,Unity 是其中最有影响力的之一。但为什么呢?让我们进一步讨论这个问题。

重要提示:

其他通用引擎的例子包括虚幻引擎、Godot、扭矩和 CryEngine。

Unity 的优势

好吧,有很多潜在原因解释了为什么 Unity 如此受欢迎。让我们列举其中一些,如下:

  • Unity 的设计初衷是简单易用,具有非常简单和精致的界面,以及少量但功能强大的工具设置。这有助于新手在启动引擎的第一秒就不会立即感到迷失。

  • Unity 的编程语言 C#对于初学者和高级程序员都非常熟悉,使用 C#进行编码的 Unity 方式简洁易懂。Unity 和 C#处理了您在其他语言中可能遇到的大部分编程问题,大大减少了您的生产时间。

  • 当移动游戏市场时代开始时,Unity 就已经存在了,它的创作者们全力以赴地创造了任何移动引擎所需的所有功能。在我看来,这是 Unity 成为今天的样子的最重要原因之一。

  • 随着其他新技术,如增强现实(AR)和虚拟现实(VR),Unity 不仅将其用于游戏,还用于应用程序、培训模拟、建筑可视化、汽车行业、电影等等。使用 Unity,您可以为广泛的行业创建应用程序,它们的使用范围每年都在增加。

  • Unity 拥有庞大的开发者社区,他们创建了参考书目和教程,提出并回答问题,并为引擎创建插件。所有这些在您开始使用 Unity 时都会有很大帮助,因为解决问题的答案只是一个谷歌搜索(有时只是几美元)之遥。

  • 由于其增长,全球范围内有大量的 Unity 工作机会,比其他游戏引擎的工作机会更多,其中一些工作机会正在寻找初级开发人员,因此新人进入这个行业的机会很大。

Unity 并非完美无缺,它也有缺点,还有其他引擎(如 Unreal Engine 4 或 Godot)与 Unity 竞争,它们在一些方面比 Unity 更好,但也有自己的缺点。在我看来,选择 Unity 还是其他引擎取决于您的意图以及您习惯使用的技术,但归根结底,您可以使用 Unity 做任何您需要做的事情,并借助其庞大的社区来解决任何弱点。现在我们了解了 Unity,让我们看看如何安装引擎。

安装 Unity

好的,经过所有这些,您已经决定选择 Unity——很好的决定!现在,我们从哪里开始呢?让我们从一个简单但必要的第一步开始:安装 Unity。这似乎是一个直接的第一步,但我们可以讨论一下正确的安装方式。在本节中,我们将讨论以下概念:

  • Unity 技术要求

  • Unity 版本

  • 安装 Unity

要运行 Unity 2020,您的计算机需要满足以下要求:

  • 如果您使用 Windows,您需要 Windows 7 SP1 或更高版本,8 或 10。Unity 只能在这些系统的 64 位版本上运行;不支持 32 位。

  • 对于 Mac,您需要 macOS High Sierra 10.13 或更高版本。

  • 对于 Linux,您需要 Ubuntu 16.04 或 18.04 或 CentOS 7。

  • 您的 CPU 需要支持 64 位和 SSE2(大多数 CPU 都支持)。

  • 具有 DirectX 10 支持的显卡(大多数现代 GPU 都支持)在 Windows 上,Mac 上支持 Metal,在 Linux 上支持 Open GL 3.2+或 Vulkan 支持。

现在我们知道了要求,让我们讨论一下 Unity 的版本控制系统。

Unity 版本

在以前的 Unity 版本中,我们通常只需下载特定 Unity 版本的安装程序,然后一直点击“下一步”直到安装完成。但是当您专业使用 Unity 时,您需要安装几个不同版本的 Unity,因为您将使用不同版本制作的不同项目。您可能会想为什么不能只使用最新的 Unity 版本来处理每个项目,但这会带来一些问题。

在 Unity 的新版本中,通常会有很多关于引擎如何工作的变化,因此您可能需要重新调整游戏的许多部分以进行升级。此外,您可能正在使用尚未适应更新的插件,因此这些插件将停止工作。在我的个人项目中,我习惯于进行项目升级;但仅仅出于学习目的,在具有特定发布日期的项目中,可能需要花费大量时间来升级整个项目,这可能会大大推迟发布日期。也许您需要一个特定的功能,该功能随着更新而带来了很大帮助。在这种情况下,升级的成本可能是值得的,但请注意,大多数情况下,这种情况并不会发生。

管理使用不同 Unity 版本制作的不同项目,安装和更新新的 Unity 版本等过去是一件很麻烦的事情,但 Unity Hub 就是为了帮助我们解决这个问题而创建的,并且已经成为安装 Unity 的默认方式。让我们更多地了解一下。

使用 Unity Hub 安装 Unity

Unity Hub 是您在安装 Unity 之前安装的一小部分软件。它集中管理所有您的 Unity 项目和安装。您可以从 Unity 官方网站获取它。下载它的步骤经常会发生变化,但在撰写本书时,您需要执行以下操作:

  1. 前往unity.com

  2. 点击开始蓝色按钮,如下截图所示:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2.1-Unity 网站上的开始按钮

  1. 点击个人选项卡,然后点击个人部分下的开始按钮,如下截图所示:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2.2-选择个人/免费许可证

  1. 点击新用户部分的从这里开始按钮,如下截图所示:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2.3-开始下载

  1. 接受条款和条件,如下截图所示:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2.4-同意隐私政策

  1. 执行下载的安装程序。

请注意,我们使用的是 Unity Hub 2.3.2,这是撰写本书时的最新版本。如果您使用更新版本,某些步骤可能会发生变化,但主要概念通常保持不变。现在我们已经安装了 Unity Hub,我们必须使用它来安装特定的 Unity 版本。您可以按照以下步骤执行:

  1. 启动 Unity Hub。

  2. 它可能会要求您创建一个 Unity 账户。如果是这样,请创建一个账户并用该账户登录。如果没有,请点击窗口右上角的人物图标,然后选择登录以有登录或创建账户的选项,如下截图所示:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2.5-登录到 Unity Hub

  1. 按照安装程序上的步骤,然后您应该会看到以下屏幕:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2.6-Unity Hub 窗口

  1. 新版本的 Unity 会指导您完成 Unity 安装和第一个项目的创建。在这种情况下,请跳过下一步,但如果您已经安装了 Unity,请按照它们的步骤进行。

  2. 点击安装按钮,检查您是否在那里列出了 Unity 2020。如果没有,请按添加按钮。确保选择了最新的 Unity 2020 版本(在我的情况下是 Unity 2020.1.0f1),然后点击下一步按钮。您的屏幕可能显示比我的更新版本,所以不用担心。该过程如下截图所示:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2.7-选择要安装的 Unity 版本

重要提示:

这是我们将在第十三章**,使用 C#进行脚本编写的介绍中使用的程序。我们现在不需要其他 Unity 功能,但如果您需要,可以随时返回并安装它们。

  1. 将会出现一个功能选择窗口。确保Microsoft Visual Studio Community被选中。在撰写本书时,最新版本是 2019,但更新版本也同样适用。现在,点击下一步按钮。该过程如下截图所示:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2.8 - 选择 Visual Studio

  1. 接受 Visual Studios 的条款和条件,如下截图所示:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2.9 - 接受 Visual Studio 的条款和条件

  1. 您将看到所选的 Unity 版本正在下载并安装。等待此过程完成。在下图中,您将看到我安装了其他 Unity 版本,但您只会看到一个版本,这是正常的:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2.10 - 我目前在计算机上安装的所有 Unity 版本

  1. 当 Unity 安装完成后,Visual Studio Installer 将自动执行。它将下载一个安装程序,该安装程序将下载并安装 Visual Studio Community 2019,如下截图所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2.11 - 安装 Visual Studio

请记住,新的 Unity 版本可能会有不同的步骤,所以尽量按照 Unity 设计的流程进行操作——大多数情况下,这是直观的。现在是使用 Unity 创建项目的时候了。

创建项目

现在我们已经安装了 Unity,可以开始创建我们的游戏了。为此,我们首先需要创建一个项目,这基本上是一个包含游戏所有文件的文件夹。这些文件称为资源,有不同类型,如图像、音频、3D 模型、脚本文件等。在本节中,我们将看到如何管理项目,涉及以下概念:

  • 创建项目

  • 项目结构

创建项目

与 Unity 安装一样,我们将使用 Unity Hub 来管理项目。我们需要按照以下步骤创建一个项目:

  1. 打开 Unity Hub,点击项目按钮,然后点击新建,如下截图所示:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2.12 - 在 Unity Hub 中创建新项目

  1. 选择通用渲染管线模板,然后输入项目名称和位置,然后点击创建。我们将创建一个简单图形的 3D 游戏,准备在 Unity 可以执行的每个设备上运行,因此通用渲染管线(或URP)是更好的选择。在第六章**,使用 URP 和 Shader Graph 进行材质和效果中,我们将详细讨论原因。该过程如下截图所示:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2.13 - 选择通用渲染管线模板

重要提示:

尝试将项目放在 Dropbox、Google Drive 或任何云同步文件夹中,以确保您随时可以使用该项目。这个项目会不断增长,所以确保您在该文件夹中有足够的空间。如果您的托管服务空间不足,可以跳过这一步。如果您知道如何使用 Git,那将是一个更好的选择。

  1. Unity 将创建并自动打开项目。这可能需要一些时间,但之后,您将看到一个类似于下图所示的屏幕:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2.14 – Unity 编辑器窗口

  1. 尝试关闭窗口,然后再次打开它,然后返回 Unity Hub 并从列表中选择项目,如下所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2.15 – 重新打开项目

现在我们已经创建了项目,让我们来探索它的结构。

项目结构

我们刚刚打开了 Unity,但在下一章之前我们不会开始使用它。现在是时候看看项目文件夹结构是如何组成的了。为此,我们需要打开创建项目的文件夹。如果您不记得这是在哪里,可以这样做:

  1. 右键单击编辑器底部的项目面板中的Assets文件夹。

  2. 单击在资源管理器中显示选项。如果您使用的是 Mac,该选项称为在 Finder 中显示。以下截图说明了这一点:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2.16 – 在资源管理器中打开项目文件夹

然后,您将看到以下文件夹结构:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2.17 – Unity 项目文件夹结构

如果您想随时将此项目移动到另一台 PC 或发送给同事,只需压缩所有这些文件并将其作为 ZIP 文件发送给他们,但并非所有文件夹都是必需的。重要的文件夹是AssetsPackagesProjectSettingsAssets 文件夹将保存我们为游戏创建和使用的所有文件,因此这是必须的。我们还将配置不同的 Unity 系统以定制引擎以适应我们的游戏。所有与此相关的设置都在ProjectSettings文件夹中。最后,我们将安装不同的 Unity 模块或包以扩展其功能,因此Packages文件夹将保存我们正在使用的模块,以便 Unity 知道。如果您需要将项目移动到其他地方,则无需复制其余文件夹,但让我们至少讨论一下Library文件夹是什么。

Unity 需要将我们将要使用的文件转换为自己的格式才能运行,一个例子就是音频和图形。Unity 支持Assets文件夹并完全重新创建Library文件夹。这个过程可能需要时间,项目越大,所需的时间就越多。

请注意,您在项目上工作时希望保留 Unity 创建的所有文件夹,因此在这期间不要删除任何文件夹,但如果您需要移动整个项目,现在您知道需要携带哪些文件。

摘要

在本章中,我们讨论了为什么 Unity 是一个用于创建游戏的好工具,并将其与市场上的其他引擎进行了比较。这个分析旨在帮助您选择 Unity 作为您的第一个游戏开发工具。之后,我们还回顾了如何使用 Unity Hub 安装和管理不同的 Unity 版本,最后,我们看到了如何使用相同的工具创建和管理多个项目。我们将经常使用 Unity Hub,因此最初了解如何使用它是很重要的。现在,我们已经准备好进入 Unity 编辑器。

在下一章中,我们将开始学习基本的 Unity 工具,以制作我们的第一级原型。

第三章:使用场景和游戏对象

欢迎来到本书的第三章—这里是艰苦工作开始的地方!在本章中,我们将开发一些关于 Unity 的基础知识,以便编辑项目。我们将看到如何使用几个 Unity 编辑器窗口来操作我们的第一个场景及其对象。此外,我们将学习如何创建和组合对象或游戏对象,以及如何使用层次结构和预制件来管理具有多个对象的复杂场景。最后,我们将回顾如何正确保存所有工作,以便以后继续工作。

具体来说,在本章中,我们将研究以下概念:

  • 操作场景

  • 游戏对象和组件

  • 对象层次结构

  • 预制件

  • 保存场景和项目

操作场景

场景是我们项目中几种文件(也称为资源)之一。根据项目类型或公司习惯的工作方式,场景可能意味着不同的事情,但最常见的用例是将游戏分成整个部分,最常见的部分包括以下内容:

  • 主菜单

  • 第 1 关,第 2 关,第 3 关,…,第 N 关

  • 胜利画面,失败画面

  • 启动画面,加载画面

在本节中,我们将涵盖与场景相关的以下概念:

  • 场景的目的

  • 场景视图

  • 我们的第一个游戏对象

  • 导航场景视图

  • 操作游戏对象

场景的目的

将游戏分成场景的想法是,您将处理并加载场景所需的数据;因此,如果您在主菜单中,您将只有该特定场景需要的纹理、音乐和对象—如果您现在不需要,就没有必要在随机存取内存RAM)中加载第 10 关的 Boss。这就是加载画面存在的原因,只是为了填补在卸载一个场景中需要的资源和加载另一个场景中需要的资源之间的时间。也许您会认为像侠盗猎车手GTA)这样的开放世界游戏在您漫游世界时没有加载画面,但实际上,它们在您移动时实际上在后台加载和卸载世界的块,而这些块是设计为彼此连接的不同场景。

主菜单和常规关卡场景之间的区别在于它们拥有的对象(也称为游戏对象)。在菜单中,您会找到背景、音乐、按钮和标志等对象,在关卡中,您将拥有玩家、敌人、平台、生命值盒等。因此,取决于您和放置在场景中的游戏对象来决定该场景对于您的游戏意味着什么。

但是我们如何创建一个场景呢?让我们从场景视图开始。

场景视图

当您打开一个 Unity 项目时,您将看到 Unity 编辑器。它将由几个窗口或面板组成,每个面板都可以帮助您更改游戏的不同方面。在本章中,我们将看看帮助您编写场景的窗口。Unity 编辑器如下截图所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3.1 – Unity 编辑器

如果您以前曾经编写过任何类型的应用程序,您可能习惯于拥有一个起始函数,比如Main,在那里您开始编写代码来创建应用程序所需的多个对象,如果我们谈论游戏,您可能会在这里创建场景中的所有对象。这种方法的问题在于,为了确保所有对象都被正确创建,您需要运行程序以查看结果,如果有什么错位,您将需要手动更改对象的坐标,这是一个缓慢而痛苦的过程。幸运的是,在 Unity 中,我们有场景视图,以下是其示例截图:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3.2 – 场景视图

这个窗口是经典WYSIWYG(所见即所得)概念的实现。在这里,您可以创建对象并将它们放置在整个场景中,通过场景预览,您可以看到当您点击播放时场景将会呈现什么样子。但在学习如何使用这个场景之前,我们需要在场景中有一个对象,所以让我们创建我们的第一个对象。

我们的第一个游戏对象

Unity 通用渲染管线URP)模板带有一个建筑工地测试场景,但让我们创建一个空的场景来开始探索这个新概念。为此,您可以简单地使用文件 | 新建场景菜单选项来创建一个空的新场景,如下截图所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3.3 – 创建一个新场景

本书将学习创建游戏对象的几种方法,但现在,让我们开始使用 Unity 提供的一些基本模板。为了创建它们,我们需要在 Unity 窗口顶部打开GameObject菜单,它将显示我们几个模板类别,如3D 对象2D 对象特效等,如下截图所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3.4 – 创建一个立方体

3D 对象类别下,我们将看到几个 3D 基本形状,如立方体球体圆柱体等,虽然使用它们不如使用精美的下载的 3D 模型令人兴奋,但请记住,我们正在原型化我们的关卡,也就是灰盒模型。这意味着我们将使用大量的原型形状来模拟我们的关卡,以便我们可以快速测试它,并查看我们的想法是否足够好,可以开始将其转换为最终版本的复杂工作。

我建议您选择立方体对象开始,因为它是一个多功能的形状,可以代表许多对象。因此,现在我们有一个带有要编辑的对象的场景,我们需要学习使用场景视图的第一件事就是浏览场景。

浏览场景视图

为了操作一个场景,我们需要学习如何在其中移动以从不同的角度查看结果。有几种导航方式,让我们从最常见的一种开始:第一人称视角。这个视图允许您使用类似第一人称射击游戏的导航方式在场景中移动,使用鼠标和WASD键。要像这样导航,您需要按住鼠标右键,然后在这样做的同时,您可以移动鼠标来旋转相机,并按下WASD键来移动它。您还可以按下Shift键以加快移动速度,并按下QE键来上下移动。

另一种常见的移动方式是单击对象以选择它(所选对象将有橙色轮廓),然后按下F键将其聚焦,使场景视图相机立即移动到一个位置,我们可以更仔细地查看该对象。之后,我们可以按住左侧Alt键和鼠标左键,开始移动鼠标以围绕对象“轨道”,看到不同的角度来检查它的每个部分是否放置正确,如下截图所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3.5 – 选择一个对象

现在我们可以自由地在场景中移动,我们可以开始使用场景视图来操作游戏对象。

操作游戏对象

场景视图的另一个用途是操作对象的位置。为了这样做,我们首先需要选择一个对象,然后按键盘上的Y键或 Unity 编辑器左上角的第六个按钮,如下截图所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3.6 – 更改变换工具

这将显示所选对象上的变换标尺,它允许我们改变对象的位置、旋转和缩放,如下截图所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3.7 – 变换标尺

让我们开始翻译物体,通过在标尺球内拖动红色、绿色和蓝色箭头来完成。在你这样做的时候,你会看到物体沿着选定的轴移动。这里有一个有趣的概念需要探索,那就是这些箭头颜色的含义。如果你注意场景视图右上角的区域,你会看到一个轴标尺,它作为这些颜色含义的提醒,如下截图所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3.8 – 轴标尺

计算机图形学使用经典的 3D 笛卡尔坐标系来表示物体的位置。红色与物体的 x 轴相关联,绿色与 y 轴相关联,蓝色与 z 轴相关联。但每个轴代表什么意思呢?如果你来自另一个 3D 制作程序,这可能会有所不同,但在 Unity 中,z 轴(蓝色)代表着前向矢量,这意味着箭头指向物体的前方;x 轴是右向矢量,y 轴代表上向矢量。需要考虑这些轴是本地的,这意味着如果你旋转物体,它们会改变它们面对的方向,因为物体的方向改变了物体面对的方式。Unity 可以在必要时显示这些轴的全局坐标,但现在让我们坚持使用本地坐标。

为了确保我们正在使用本地坐标,确保本地模式已激活,如下截图所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3.9 – 在枢轴和本地坐标之间切换

如果你看到全局而不是本地作为右侧按钮,只需点击它就会改变。顺便说一下,尽量保持左侧按钮为枢轴。如果它显示中心,只需点击它进行更改。

我知道——我们正在编辑一个立方体,所以没有明显的前面或右侧,但当你使用真实的 3D 模型,比如汽车和角色时,它们肯定会有这些面,而且它们必须与这些轴正确对齐。如果将来你在 Unity 中导入一辆汽车,汽车的前面指向红轴(X 轴),你需要修正它,因为我们未来的移动代码将依赖于这个约定,但让我们留到以后再说。

现在,让我们使用这个变换标尺来旋转物体,使用它周围的三个彩色圆圈。例如,如果你点击并拖动红色圆圈,你会沿着 x 旋转轴旋转物体。这里还有一个有趣的提示需要考虑。如果你想根据我们之前讨论的颜色编码来水平旋转物体,你可能会选择 x 轴——用于水平移动的轴——但很遗憾,那是错误的。

旋转的一个好方法就像自行车的加速器:你需要拿着它并转动。如果你像这样旋转 x 轴,你会使物体上下旋转。所以,为了水平旋转,你需要使用绿色圆圈或 y 轴。这个过程如下截图所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3.10 – 旋转物体

最后,我们有缩放,通过变换标尺球外侧的彩色立方体来完成。如果你点击并拖动它们,你会看到我们的立方体沿着这些轴被拉伸,允许你改变物体的大小。此外,你会看到标尺中心有一个灰色立方体,它允许你统一沿着所有轴改变物体的大小。这个过程如下截图所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3.11 – 缩放对象

记住,在许多情况下,缩放对象通常是一个不好的做法。在你场景的最终版本中,你将使用适当大小和比例的模型,并且它们将以模块化的方式设计,这样你可以将它们一个接一个地连接起来。如果你对它们进行缩放,可能会发生一些不好的事情,比如纹理被拉伸并变得像素化,以及不再正确连接的模块。当然也有一些例外,比如在森林中放置大量相同树木的实例,并稍微改变它的比例以模拟变化,以及在灰盒阶段,将立方体改变比例以创建地板、墙壁、天花板、柱子等是完全可以的,因为最终,这些立方体将被真正的 3D 模型替换。

挑战

创建一个由地板、三面普通墙和一个带门洞的第四面墙(三个立方体)组成的房间。在下面的截图中,你可以看到它应该是什么样子的:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3.12 – 房间任务完成

现在我们可以编辑对象的位置,让我们看看如何编辑它的其他方面。

游戏对象和组件

我们谈到我们的项目由资源组成,场景(一种特定类型的资源)由游戏对象组成;那么,我们如何创建一个对象呢?通过组件的组合。

在本节中,我们将涵盖与组件相关的以下概念:

  • 组件

  • 操作组件

组件

组件是游戏对象可以由多个部分组成的其中之一;每个组件负责对象的不同特性。有几个组件可以解决不同的任务,比如播放声音,渲染网格,应用物理等等,即使 Unity 有大量的组件,我们最终还是需要创建自定义组件,迟早会用到。在下面的截图中,你可以看到当我们选择一个游戏对象时 Unity 向我们展示的内容:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3.13 – 检视面板

在前面的截图中,我们可以看到检视面板,如果我们需要猜测它的作用,我们现在可以说它显示了所选对象的所有属性,并且我们可以配置它们来改变对象的行为,比如位置和旋转,是否投射阴影等等。这是正确的,但我们缺少一个关键元素:这些属性不属于对象;它们属于对象的组件。我们可以在一组属性之前看到一些标题加粗,比如变换盒碰撞器等等。这些是对象的组件。

在这种情况下,我们的对象有一个变换、一个网格过滤器、一个网格渲染器和一个盒碰撞器组件,所以让我们逐个审查这些。变换只有位置信息,比如对象的位置、旋转和比例,它本身什么也不做——它只是我们游戏中的一个点——但当我们向对象添加组件时,那个位置开始变得更有意义。这是因为一些组件将与变换和其他组件互动,每一个都会影响其他。

一个例子是网格过滤器网格渲染器,它们都负责渲染 3D 模型。网格渲染器将在网格过滤器中指定的网格在变换组件中指定的位置上渲染,所以网格渲染器需要从这些其他组件获取数据,没有它们就无法工作。另一个例子是盒碰撞器。它代表了对象的物理形状,所以当物理计算对象之间的碰撞时,它会检查该形状是否与其他形状基于变换中指定的位置发生碰撞。

我们现在不想探索物理和渲染。本节的要点是 GameObject 是一组组件,每个组件为我们的对象添加特定的行为,并且每个组件与其他组件互动以完成所需的任务。为了进一步加强这一点,让我们看看如何将一个立方体转换成一个使用物理下落的球体。

操作组件

编辑对象组件的工具是检视器。它不仅允许我们更改组件的属性,还允许我们添加和移除组件。在这种情况下,我们想要将一个立方体转换成一个球体,因此我们需要改变这些组件的几个方面。我们可以从改变对象的视觉形状开始,因此我们需要改变渲染模型或网格。指定要渲染的网格的组件是MeshFilter组件。如果我们看一下,我们可以看到一个说CubeMesh属性,右边有一个带点的小圆圈。

重要提示

如果您没有看到任何像我们刚提到的网格的属性,请尝试点击组件名称左侧的三角形。这样做将展开和折叠所有组件的属性。这在下面的截图中有所说明:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3.14 – 禁用组件

如果我们点击它,选择网格窗口将弹出,允许我们选择几个网格选项;因此,在这种情况下,选择Sphere组件。在将来,我们将向我们的项目添加更多的 3D 模型,以便该窗口将有更多的选项。网格选择器显示在下面的截图中:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3.15 – 网格选择器

好了,看起来像一个球体,但它会像一个球体一样行为吗?让我们找出来。为了这样做,我们可以在窗口顶部的搜索框中添加一个Rigidbody。下面的截图说明了如何添加一个组件:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3.16 – 添加组件

如果您点击编辑器顶部中间的播放按钮,您可以使用游戏面板测试您的球体物理。当您点击播放时,该面板将自动聚焦,并向您展示玩家将如何看到游戏。这里可能出现的一个问题是,也许您看不到任何东西,如果游戏摄像机没有指向我们的球体所在的位置,那就可能会发生这种情况。播放控制显示在下面的截图中:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3.17 – 播放控制

在这里,您可以使用变换图标来旋转和定位摄像机,使其以某种方式看向我们的球体。在移动时,您可以在场景窗口的右下部分检查小预览,以查看新的摄像机视角。另一种选择是在层次结构中选择摄像机,然后使用快捷键Ctrl + Shift + F(或 Mac 上的command + Shift + F)。摄像机预览显示在下面的截图中:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3.18 – 摄像机预览

现在,为了测试物理碰撞是否执行正常,让我们创建一个立方体,将其缩放直到它呈坡道形状,并将该坡道放在我们的球体下方,如下所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3.19 – 球和坡道对象

如果您现在点击播放,您将看到球体与我们的坡道发生碰撞,但方式很奇怪。看起来像是在弹跳,但实际并非如此。如果您展开球体的Box Collider组件,您将看到即使我们的物体看起来像一个球体,绿色的框图标显示我们的球体实际上是一个盒子在物理世界中,如下面的截图所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3.20 - 具有球形图形和盒碰撞器的对象

如今,视频卡可以处理渲染高度详细的模型(具有高多边形数量),但是物理系统是在中央处理单元CPU)中执行的,它需要进行复杂的计算以侦测碰撞。为了在我们的游戏中获得良好的性能(至少 30帧每秒FPS)),物理系统使用简化的碰撞形状来工作,这些形状可能与玩家在屏幕上看到的实际形状不同。这就是为什么我们有Mesh Filter和不同类型的碰撞器组件分开——一个处理视觉形状,另一个处理物理形状。

再次强调,本节的目的不是深入研究这些 Unity 系统,所以让我们继续前进。我们如何解决这个问题呢?简单:通过修改我们的组件!在这种情况下,BoxCollider可以表示一个盒子形状,不像MeshFilter,它支持任何形状。因此,首先我们需要通过右键单击组件的标题并选择移除组件选项来移除它,如下面的屏幕截图所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3.21 - 移除组件

现在,我们可以再次使用添加组件菜单来选择一个物理组件,这次选择球体碰撞器组件。如果您查看物理组件,您将看到其他类型的碰撞器,可以用来表示其他形状,但我们将在第十五章**,物理碰撞和健康系统中进行讨论。球体碰撞器组件可以在下面的屏幕截图中看到:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3.22 - 添加一个球体碰撞器组件

因此,如果您现在点击播放,您将看到我们的球体不仅外观像一个球体,而且行为也像一个球体。记住:本书本节的主要思想是理解在 Unity 中,您可以通过添加、移除和修改组件来创建任何您想要的对象,我们将在整本书中大量使用这种方法。

现在,组件不是创建对象所需的唯一内容。复杂的对象可能由多个子对象组成,因此让我们看看它是如何工作的。

对象层次结构

一些复杂的对象可能需要分成子对象,每个子对象都有自己的组件。这些子对象需要以某种方式附加到主对象,并共同工作以创建必要的对象行为。

在本节中,我们将涵盖与组件相关的以下概念:

  • 对象的父子关系

  • 可能的用途

对象的父子关系

父子关系包括使一个对象成为另一个对象的子对象,这意味着这些对象将彼此相关联。发生的一种关系类型是变换关系,意味着子对象将受到父对象变换的影响。简单来说,子对象将跟随父对象,就像它附加在上面一样。举个例子,想象一个戴着帽子的玩家。帽子可以是玩家头部的子对象,使帽子在附着时跟随头部移动。

为了尝试这个,让我们创建一个代表敌人的胶囊体和一个代表敌人武器的立方体。请记住,为了这样做,您可以使用GameObject | 3D Object | CapsuleBox选项。一个示例胶囊体可以在下面的屏幕截图中看到:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3.23 - 代表人类的胶囊体和代表武器的盒子

如果您移动敌人对象(胶囊体),武器(盒子)将保持其位置,而不会跟随我们的敌人。因此,为了防止这种情况发生,我们可以简单地将武器拖到层次结构窗口中的敌人对象上,如下面的屏幕截图所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3.24 - 将立方体武器作为胶囊角色的父对象

现在,如果你移动敌人,你会看到枪也随之移动、旋转和缩放。所以,基本上,枪的变换也受到敌人变换组件的影响。

现在我们已经做了一些基本的父子关系,让我们继续探索其他可能的用途。

可能的用途

除了创建复杂对象之外,父子关系还有一些其他常见的用途。其中一个常见的用途是组织项目的层次结构。现在,我们的场景很简单,但随着时间的推移,它会变得更加复杂,因此跟踪所有对象将变得困难。为了防止这种情况发生,我们可以创建空的游戏对象(在GameObject | Create Empty中),充当容器,将对象放入其中,以便组织我们的场景。请谨慎使用这个功能,因为如果滥用,会有性能成本。通常情况下,在组织场景时,有一到两级的父子关系是可以接受的,但超过这个数量可能会影响性能。请考虑,你可以并且将会在创建复杂对象时有更深层次的父子关系;所提出的限制只是用于场景组织。

为了不断改进我们之前的示例,在整个场景中复制敌人几次,创建一个名为敌人的空游戏对象,并将所有敌人拖放到其中,使其充当容器。如下截图所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3.25 - 将敌人分组在父对象中

父子关系的另一个常见用途是改变对象的枢轴或中心。现在,如果我们尝试用变换控件旋转我们的枪,它会围绕它的中心旋转,因为立方体的创建者决定将中心放在那里。通常情况下,这是可以接受的,但让我们考虑这样一种情况,即我们需要让武器瞄准敌人所看的点。在这种情况下,我们需要围绕武器手柄旋转武器;所以,在这个"盒子"武器的情况下,它将是最接近敌人的一端。问题在于我们无法改变对象的中心,因此一个解决方案是创建另一个具有不同中心的"武器"3D 模型或网格,这将导致大量重复的武器版本,如果我们考虑到其他可能的游戏需求,比如旋转武器拾取物品。我们可以很容易地使用父子关系来解决这个问题。

这个想法是创建一个空的游戏对象,并将其放在我们希望对象的新枢轴的位置。之后,我们可以简单地将我们的武器拖放到这个空的游戏对象中,并且从现在开始,将空对象视为实际的武器。如果你旋转或缩放这个武器容器,你会发现武器网格会围绕这个容器应用这些变换,所以我们可以说武器的枢轴已经改变了(实际上并没有,但我们的容器模拟了这种变化)。这个过程如下截图所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3.26 - 改变武器的枢轴

现在,让我们继续看看不同的管理游戏对象的方法,这次使用预制体。

预制体

在前面的例子中,我们在场景中创建了许多敌人的副本,但在这样做的过程中,我们创建了一个新问题。让我们想象一下,我们需要改变我们的敌人并给它添加一个Rigidbody组件,但因为我们有几个相同对象的副本,我们需要逐个将它们添加相同的组件。也许以后,我们需要改变每个敌人的质量,所以再一次,我们需要逐个地去改变每一个敌人,这里我们可以开始看到一个模式。

一个解决方案可能是使用Ctrl键(Mac 上的option键)选择所有的敌人并一次修改它们,但如果我们在其他场景中有敌人的副本,这个解决方案就没有用了。这就是预制体的用武之地。

在本节中,我们将涵盖与预制体相关的以下概念:

  • 创建预制体

  • 预制体实例关系

  • 预制体变体

创建预制体

预制体是 Unity 工具,允许我们将自定义对象,比如我们的敌人,转换为定义它们如何创建的资源。我们可以使用它们轻松地创建自定义对象的新副本,而不需要再次创建其组件和子对象。

为了创建一个预制体,我们可以简单地将自定义对象从层次结构窗口拖动到项目窗口,这样做之后,你会在项目文件中看到一个新的资源。项目窗口是你可以浏览和探索所有项目文件的地方;所以,在这种情况下,我们的预制体是我们创建的第一个资源。现在,你可以简单地将预制体从项目窗口拖到场景中,轻松地创建新的预制体副本,如下面的截图所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3.27 - 创建预制体

现在,我们有一个小问题。如果你注意层次结构窗口,你会看到原始预制体对象和所有新副本,它们的名称是蓝色的,而在预制体之前创建的敌人的名称是黑色的。名称中的蓝色表示该对象是预制体的实例,意味着该对象是基于预制体创建的。我们可以选择这些蓝色命名的对象,并在检视器中点击选择按钮,选择创建该对象的原始预制体。这在下面的截图中有所说明:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3.28 - 在层次结构中检测预制体

所以,问题在于之前的预制体副本不是原始预制体的实例,遗憾的是没有办法使它们与预制体连接起来。因此,为了实现这一点,我们需要简单地销毁旧的副本,并用预制体创建的副本替换它们。起初,没有所有副本都作为实例似乎不是一个问题,但在本章的下一节中,我们将探讨预制体和它们的实例之间的关系。

预制体实例关系

预制体的实例具有与预制体的绑定,有助于在它们之间轻松地恢复和应用更改。如果你拿一个预制体并对其进行一些修改,这些更改将自动应用到项目中所有场景中的所有实例,因此我们可以轻松地创建预制体的第一个版本,在整个项目中使用它,然后尝试进行更改。

为了练习这一点,假设我们想要给敌人添加一个Rigidbody组件,以便它们可以下落。为了做到这一点,我们可以简单地双击预制体文件,进入预制体编辑模式,在这里,我们可以编辑预制体,与场景中的其余部分隔离开来。在这里,我们可以简单地取出预制体根对象,并向其添加Rigidbody组件。之后,我们可以简单地点击场景窗口左上角的场景按钮,回到我们正在编辑的场景,现在,我们可以看到所有敌人的预制体实例都有Rigidbody组件,如下面的截图所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3.29 - 预制体编辑模式

现在,如果我们改变了一个预制体实例会发生什么呢?比如说我们想让一个特定的敌人飞行,这样他们就不会受到重力的影响。我们只需选择特定的预制体,取消刚体组件中的使用重力复选框。这样做后,如果我们玩游戏,我们会看到只有那个特定实例会飘浮。这是因为预制体实例的更改变成了覆盖,如果你看检视器中的该实例的使用重力属性变成了粗体,你就可以清楚地看到这一点。让我们拿另一个对象,改变它的缩放属性使其变大。同样,我们会看到缩放属性变成了粗体,并且左侧有一个小条。使用重力复选框可以在下面的截图中看到:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3.30 – 使用重力被突出显示为覆盖

覆盖优先于预制体,因此如果我们改变原始预制体的缩放,具有缩放覆盖的预制体不会改变,保持其自己的缩放版本,如下截图所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3.31 – 一个带有缩放覆盖的预制体实例

我们可以使用检视器中的覆盖下拉菜单轻松定位实例的所有覆盖,找到我们对象的所有更改。它不仅允许我们查看所有覆盖,还可以撤销我们不想要的任何覆盖并应用我们想要的覆盖。比如说,我们后悔了特定预制体缺乏重力,没问题!我们只需找到覆盖并撤销它。该过程如下截图所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3.32 – 撤销单个覆盖

另外,假设我们真的喜欢那个实例的新缩放,所以我们希望所有实例都具有那个缩放—太棒了!我们只需点击应用按钮,选择特定的更改,所有实例都会具有那个缩放(除了具有覆盖的实例),如下截图所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3.33 – 应用按钮

此外,我们还有撤销所有应用所有按钮,但要谨慎使用,因为你可能会轻易撤销和应用你不知道的更改。

因此,正如你所看到的,预制体是一个非常有用的 Unity 工具,可以跟踪所有相似的对象并对它们应用更改,并且还可以具有具有少量变化的特定实例。谈到变化,还有其他情况,你会希望有几个具有相同变化集的预制体实例,比如飞行敌人和地面敌人,但是如果你考虑一下,我们在不使用预制体时遇到的问题是一样的,所以我们需要手动逐个更新这些不同版本。

在这里,我们有两个选择:一个是创建一个全新的预制体,只是为了有另一个带有那种变化的版本。这会导致一个问题,如果我们希望所有类型的敌人都受到更改,我们需要手动将更改应用到每个可能的预制体。第二个选择是创建一个预制体变体。让我们来看看后者。

预制体变体

预制体变体是创建一个新的预制体,但基于现有预制体的行为,因此新的预制体继承了基础预制体的特性。这意味着我们的新预制体可以与基础预制体有所不同,但它们共有的特性仍然是相连的。

为了说明这一点,让我们创建一个可以飞行的敌人预制件的变体:飞行敌人预制件。为此,我们可以在“层次结构”窗口中选择现有的敌人预制件实例,将其命名为“飞行敌人”,然后再次将其拖到“项目”窗口中,这次会看到一个提示,询问我们要创建哪种预制件。这次,我们需要选择“预制件变体”,如下截图所示:

图 3.34 - 创建预制件变体

](https://github.com/OpenDocCN/freelearn-csharp-zh/raw/master/docs/hsn-unity20-gm-dev/img/Figure_3.34_B14199.jpg)

图 3.34 - 创建预制件变体

现在,我们可以通过双击进入变体的预制件编辑模式,然后添加一个立方体作为我们敌人的喷气背包,并取消敌人的“使用重力”属性。如果我们返回到场景,我们将看到变体实例已经更改,而基本敌人没有改变。您可以在下面的截图中看到这一点:

图 3.35 - 预制件变体实例

](https://github.com/OpenDocCN/freelearn-csharp-zh/raw/master/docs/hsn-unity20-gm-dev/img/Figure_3.35_B14199.jpg)

图 3.35 - 预制件变体实例

现在,想象一下您想要为我们所有类型的敌人添加一个帽子。我们只需双击基本敌人预制件进入预制件编辑模式,然后添加一个立方体作为帽子。现在,我们将看到该更改应用于所有敌人,因为请记住:“飞行敌人”预制件是基本敌人预制件的变体,这意味着它将继承所有更改。

到目前为止,我们已经创建了大量内容,但是如果我们的电脑因某种原因关闭,我们肯定会丢失所有内容,所以让我们看看如何保存我们的进度。

保存场景和项目

与任何其他程序一样,我们需要保存我们的进度。不同之处在于,我们不只有一个包含所有项目资产的巨大文件,而是每个资产都有几个文件。

在本节中,我们将涵盖以下与保存相关的概念:

  • 保存我们的更改

  • 项目结构

保存我们的更改

让我们开始通过保存场景来保存我们的进度,这非常简单。我们只需转到项目的“资产”文件夹,但永远不要超出该文件夹。这将在“项目”窗口中生成一个新的资产:一个场景文件,如下截图所示:

图 3.36 - 场景文件

](https://github.com/OpenDocCN/freelearn-csharp-zh/raw/master/docs/hsn-unity20-gm-dev/img/Figure_3.36_B14199.jpg)

图 3.36 - 场景文件

我们可以在对话框中创建一个文件夹来保存我们的场景,或者,如果您已经保存了场景,可以在“项目”窗口中使用“创建”|“文件夹”选项创建一个文件夹,并将创建的场景拖到该文件夹中。现在,如果您使用“文件”|“新建场景”菜单选项创建另一个场景,您可以通过在“项目”窗口中双击资产来返回到先前的场景。

这只保存了场景,但是对预制件和其他类型的资产的任何更改都不会使用该选项保存。相反,如果您想保存除场景之外的所有资产的每个更改,可以使用“文件”|“保存项目”选项。这可能有点令人困惑,但是如果您想保存所有更改,您需要同时保存场景和项目,因为仅保存项目不会保存场景上的更改。有时,确保一切都已保存的最佳方法就是关闭 Unity,这在尝试在计算机或文件夹之间移动项目时是推荐的。让我们在下一节中讨论这个问题。

项目结构

现在我们已经保存了所有更改,我们准备好将项目在计算机之间或到另一个文件夹中移动(如果有需要的话)。您可以关闭 Unity 以确保一切都已保存,并只需复制整个项目文件夹。如果您不记得在哪里保存了项目,您可以右键单击“项目”窗口中的“资产”文件夹,然后选择“在资源管理器中显示”(Mac 上的“显示在 Finder 中”),如下截图所示:

图 3.37 - 定位项目文件夹

](https://github.com/OpenDocCN/freelearn-csharp-zh/raw/master/docs/hsn-unity20-gm-dev/img/Figure_3.37_B14199.jpg)

图 3.37 - 定位项目文件夹

现在我们在项目文件夹中,让我们抓住机会稍微探索一下。在一个完整的项目中,我们会发现几个文件夹和文件,但并非所有文件都需要复制以便将项目移动到其他地方。最重要的文件夹是AssetsProjectSettingsPackages。这些文件夹可以在以下截图中看到:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3.38 - 项目文件夹结构

ProjectSettings文件夹包含了我们将在本书后面玩弄的不同 Unity 系统的几个配置,但即使我们没有更改任何设置,带上这个文件夹总是一个好主意。.unitypackage文件曾经是,但让我们稍后讨论。到目前为止,重要的是要注意,该文件夹将包含关于我们的项目正在使用哪些包的设置,因此也记得带上它。

其他文件夹/文件都不是必需的,因为其中一些是临时的,另一些可以重新生成,比如Library,那里存放着我们资产的转换版本。通过转换,我们指的是外部生成的文件,比如 3D 模型、图像、声音等。Unity 需要将这些文件转换为 Unity 兼容的格式。原始文件将存放在Assets中,转换后的文件将存放在Library中,以便在必要时可以轻松重新生成。稍后,在第五章**,导入和集成资产中,我们将讨论如何集成外部生成的内容。

现在,让我们想象一下,你已经压缩了这三个文件夹,将它们复制到 U 盘中,然后在另一台电脑上解压这些文件夹。我们如何再次打开项目呢?正如你所看到的,项目没有项目文件或类似的东西 - 它只是一堆文件夹。为了打开一个项目,最简单的方法是在Assets文件夹中找到一个场景文件,然后双击它,这样 Unity 就会在那个场景中打开项目。另一个选项是使用Assets文件夹。因此,我们将把该项目添加到我们计算机项目的列表中,稍后,我们只需点击列表中的名称即可打开它。以下截图说明了这一点:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3.39 - 重新打开项目

现在,我们已经掌握了开始学习如何使用不同的 Unity 系统所需的所有基本 Unity 知识,以便开始创建一个真正的游戏!让我们在下一章中做到这一点!

总结

在本章中,我们简要介绍了基本的 Unity 概念。我们回顾了所有 Unity 窗口以及如何使用它们来编辑一个完整的场景,从导航和创建预制对象,到操纵它们以创建我们自己类型的对象,使用游戏对象和组件。我们还讨论了如何使用Hierarchy窗口将游戏对象进行父子关系,以创建复杂的对象层次结构,以及创建预制件以重用和操纵大量相同类型的对象。最后,我们讨论了如何保存我们的进度并移动项目,回顾了项目的结构以及哪些文件夹是必不可少的。

在下一章中,我们将学习使用不同的工具来创建游戏关卡的第一个原型。

第四章:使用地形和 ProBuilder 进行灰盒设计

现在我们已经掌握了使用 Unity 所需的所有概念,让我们开始设计我们的第一个关卡。本章的想法是学习如何使用地形工具来创建游戏的景观,然后使用 ProBuilder 来创建基础的 3D 网格,比使用立方体具有更多的细节。使用这些工具,您将能够创建任何类型的场景原型,并在实际实现最终图形之前尝试您的想法。

具体来说,在本章中,我们将讨论以下概念:

  • 使用地形创建景观

  • 使用 ProBuilder 创建形状

使用地形创建景观

到目前为止,我们已经使用立方体生成了我们的关卡原型,但我们也了解到,有时这些形状无法代表我们可能需要的所有对象。想象一下不规则的东西,比如丘陵、峡谷和河流的完整地形。使用立方体创建这将是一场噩梦。另一个选择是使用 3D 建模软件,但问题是生成的模型将如此庞大和详细,以至于即使在高端 PC 上也无法良好运行。在这种情况下,我们需要学习如何使用地形,这将是本章的第一节中我们要做的事情。

在本节中,我们将涵盖与地形相关的以下概念:

  • 讨论高度图

  • 创建和配置高度图

  • 编写高度图

  • 添加高度图细节

让我们开始谈论高度图,其纹理帮助我们定义地形的高度。

讨论高度图

如果我们使用常规的 3D 建模工具创建一个巨大的游戏区域,包括丘陵、峡谷、陨石坑、山谷和河流,我们将面临一个问题,即我们将在所有可能的距离上使用完整详细的模型,从而浪费资源在远处看不到的细节上。我们将从很远的地方看到很多地形部分,比如山脉和河流,所以这是一个严重的问题。

Unity 地形工具使用一种称为高度图的技术以高效和动态的方式生成地形。它不是为整个地形生成大型 3D 模型,而是使用一种称为高度图的图像,看起来像地形的俯视黑白照片。

在下图中,您可以看到苏格兰地形高度的黑白俯视图,白色表示较高的高度,黑色表示较低的高度:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.1 - 苏格兰的高度图

在上图中,您可以很容易地在寻找图像中最白的区域时发现山峰。海平面以下是黑色的,而中间使用灰度渐变的任何东西代表了最小和最大高度之间的不同高度。想法是图像的每个像素确定了地形特定区域的高度。

Unity 地形工具可以自动生成地形的 3D 网格,从而节省了完整地形的 3D 模型的硬盘空间。此外,Unity 将随着我们移动创建地形,为附近区域生成高详细度模型,并为远处区域生成低详细度模型,使其成为一种高效的解决方案。

在下图中,您可以看到为地形生成的网格。您可以看到地形的近处部分比远处部分有更多的多边形:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.2 - 高度图生成的网格

请注意,这项技术也有其缺点,比如 Unity 在我们玩游戏时生成这些 3D 模型所需的时间,以及无法创建洞穴,但目前对我们来说这不是问题。

现在我们知道了什么是高度图,让我们看看如何使用 Unity 地形工具来创建我们自己的高度图。

创建和配置高度图

如果单击GameObject | 3D Object | Terrain,您将看到一个巨大的平面出现在场景中,并且Hierarchy窗口中出现了一个 Terrain 对象。这就是我们的地形,它是平的,因为它的高度图一开始就是全黑的,因此在其初始状态下没有任何高度。在下面的截图中,您可以看到全新的Terrain是什么样子的:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.3 - 尚未绘制高度的地形

在开始编辑地形之前,您必须配置不同的设置,例如地形的高度图的大小和分辨率,这取决于您打算如何使用它。这与生成整个世界不同。请记住,我们的游戏将发生在玩家的基地,因此地形将很小。在这种情况下,200 x 200 米大小的区域被山脉包围将足够。

为了根据这些要求配置我们的地形,我们需要执行以下操作:

  1. HierarchyScene窗口中选择Terrain

  2. 查看Terrain组件的Inspector,如果折叠了,请展开它。

  3. 单击轮子图标以切换到配置模式。在下面的截图中,您可以看到该按钮的位置:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.4 - 地形设置按钮

  1. 查找Mesh Resolution部分。

  2. 更改200。这将说明我们的地形尺寸为 200 x 200 米。

  3. 500只是为了限制我们山的最高峰:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.5 - 地形分辨率设置

  1. 查找Texture Resolutions部分。

  2. Heightmap Resolut更改为257 x 257

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.6 - 高度图分辨率设置

重要提示

高度图分辨率是将保存地形不同部分的高度的高度图图像的大小。在我们的 200 x 200 米地形中使用 257 x 257 的分辨率意味着地形中的每个平方米将被高度图的略多于 1 像素覆盖。每平方米的分辨率越高,您可以在该区域大小中绘制的细节就越多。通常,地形特征很大,因此每平方米多于 1 像素通常是资源浪费。找到允许您创建所需细节的最小分辨率。

您还需要设置的初始设置是初始地形高度。默认情况下,这是 0,因此您可以从底部开始绘制高度,但这样做,您无法在地形中开洞,因为它已经处于最低点。设置一点初始高度允许您绘制河流路径和必要时开洞。为此,请执行以下操作:

  1. 选择Terrain

  2. 单击Brush按钮(第二个按钮)。

  3. 将下拉菜单设置为Set Height

  4. 50。这将说明我们希望所有地形的起始高度为50米,从而允许我们最大深度为50米的洞:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.7 - 设置高度地形工具位置

  1. 单击我们之前指定的50米。

现在我们已经正确配置了我们的高度图,让我们开始编辑它。

编写高度图

请记住,高度图只是一个带有高度的图像,因此为了编辑它,我们需要在该图像中绘制高度。幸运的是,Unity 有工具可以让我们直接在编辑器中编辑地形并直接查看修改后的高度结果。为此,我们必须按照以下步骤进行:

  1. 选择Terrain

  2. 单击Brush按钮。

  3. 将下拉菜单设置为提高或降低地形模式:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.8 - 提高或降低地形工具位置

  1. 选择画笔选择器中的第二个画笔。这个画笔的边缘模糊,可以让我们创建更柔和的高度。

  2. 画笔大小设置为30,这样我们就可以创建跨越30米区域的高度。如果你想创建更细微的细节,你可以减小这个数字。

  3. 不透明度设置为10,以减少每秒或每次点击绘制的高度量:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.9 - 光滑边缘画笔

  1. 现在,如果你在场景视图中移动鼠标,你会看到你点击该区域时将绘制的高度的一个小预览。也许你需要靠近地形才能看清楚:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.10 - 提升地形区域的预览

重要提示

你在地形附近看到的方格图案可以让你看到你正在编辑的对象的实际大小。每个单元格代表一个平方米。记住,有一个参考来看到你正在编辑的对象的实际大小是有用的,可以防止创建太大或太小的地形特征。也许你可以放入其他类型的参考,比如一个具有准确尺寸的大立方体,代表一个建筑的大小,以便了解你正在创建的山或湖的大小。记住,立方体的默认尺寸是 1 x 1 x 1 米,所以缩放到(10,10,10)将给你一个 10 x 10 x 10 米的立方体。

  1. 按住左键并拖动鼠标在地形上开始绘制地形高度。记住,你可以按下Ctrl + Z(Mac 上为command+ Z)来撤销任何不需要的更改。

  2. 尝试绘制围绕我们区域边界的山脉,这将代表我们基地的背景山丘:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.11 - 绘制在地形边缘的山脉

现在,我们在未来基地周围有了不错的起始山丘。我们还可以在未来基地区域周围绘制一个河流流域。要这样做,请按照以下步骤进行:

  1. 在地形的中间放置一个缩放为(50,10,50)的立方体。这将作为我们即将创建的基地的占位符:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.12 - 基地区域的占位立方体

  1. 再次选择地形画笔按钮。

  2. 画笔大小减小到10

  3. 按住Shift键,左键单击并拖动鼠标在地形上绘制我们基地占位符周围的流域。这样做会降低地形而不是提升它:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.13 - 我们占位基地周围的河流流域

现在,我们有了一个简单但不错的起始地形,让我们对从基地的角度看它的外观有了基本的了解。在继续之前,我们将应用一些更精细的细节,使我们的地形看起来更好一些。在下一节中,我们将讨论如何使用不同的工具模拟地形侵蚀。

添加高度图细节

在前一节中,我们创建了地形的粗略轮廓。如果你想让它看起来更真实一些,那么你需要开始在各处绘制许多微小的细节。通常,这是在关卡设计过程的后期完成的,但是让我们现在来看看,因为我们正在探索地形工具。现在,我们的山看起来非常平滑。在现实生活中,它们更加陡峭,所以让我们改进一下:

  1. 选择地形并启用画笔按钮。

  2. 设置下拉菜单为提升或降低地形模式。

  3. 选择第五个画笔。这个画笔的布局不规则,这样我们就可以在各处绘制一些噪音。

  4. 画笔大小设置为50,这样我们就可以覆盖更大的区域:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.14 - 云图案画笔用于随机性

  1. 按住Shift键,对地形的山丘进行小幅点击,不要拖动鼠标。记得放大到你正在应用细节的区域,因为这些在远处看不到:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.15 – 用之前的刷子生成的侵蚀

这给我们的山丘增加了一些不规则性。现在,让我们想象我们想在山丘上有一个平坦的区域,可以放置装饰性的天文台或天线。按照以下步骤操作:

  1. 选择地形刷工具,并从下拉菜单中选择设置高度

  2. 高度设置为60

  3. 在山丘上涂抹一个区域。你会看到如果低于60米,地形会升高,或者在大于60米的区域变得更低:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.16 – 平坦的山丘

  1. 你可以看到边界有一些粗糙的角落需要平滑:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.17 – 未平滑的地形边缘

  1. 将下拉菜单更改为平滑高度模式。

  2. 选择尺寸为5,不透明度为10的第二个刷子:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.18 – 平滑高度刷

  1. 点击并拖动我们平坦区域的边界,使它们更加平滑:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.19 – 平滑的地形边缘

我们可以在这里和那里不断添加细节,但现在我们可以就此结束。下一步是创建我们的玩家基地,但这次,让我们探索 ProBuilder 以生成我们的几何图形。

使用 ProBuilder 创建形状

到目前为止,我们使用立方体和基本形状创建了简单的场景,对于大多数原型来说已经足够了,但有时,你可能会遇到游戏中难以用普通立方体建模的棘手区域,或者你可能想在游戏的某些部分添加更深层次的细节,以便让玩家感受到该区域的视觉效果。在这种情况下,我们可以使用任何 3D 建模工具,比如 3D Studio、Maya 或 Blender,但这些工具可能难以学习,而且在开发的这个阶段你可能不需要它们的全部功能。幸运的是,Unity 有一个名为 ProBuilder 的简单 3D 模型创建工具,让我们来探索一下。

在本节中,我们将涵盖与 ProBuilder 相关的以下概念:

  • 安装 ProBuilder

  • 创建一个形状

  • 操作网格

  • 添加细节

ProBuilder 不是默认包含在我们的 Unity 项目中的,所以让我们从学习如何安装它开始。

安装 ProBuilder

Unity 是一个功能强大的引擎,但如果我们没有使用所有这些工具,会使引擎运行变慢,因此我们需要手动指定我们正在使用哪些 Unity 工具。为此,我们将使用包管理器,这是一个工具,我们可以用它来查看和选择我们将需要哪些 Unity 包。你可能还记得,之前我们谈到过Packages文件夹。这基本上就是包管理器在修改的内容。

为了使用这个工具安装 ProBuilder,我们需要执行以下操作:

  1. 点击窗口 | 包管理器选项:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.20 – 包管理器选项

  1. 在刚刚打开的窗口中,确保Packages处于Unity Registry模式,方法是点击窗口左上角的Packages按钮,然后选择Unity Registry外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.21 – 显示所有包

  1. 等待一会儿,直到左侧的包列表填满。确保连接到互联网以下载和安装包。

  2. 看看那个列表中的ProBuilder包,并选择它。

重要提示

我正在使用 ProBuilder 4.2.3 版本,这是我写这本书时可用的最新版本。虽然您可以使用更新的版本,但请考虑使用它的步骤可能会有所不同。您可以使用标题左侧的箭头查看旧版本。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.22 - 在包列表中的 ProBuilder

  1. 单击Package Manager右下角的Install按钮:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.23 - 安装按钮

  1. 等待一会儿,直到包安装完成。当Install按钮被替换为 Up to Date 标签时,您会注意到过程已经结束。

既然我们已经在项目中安装了 ProBuilder,让我们来使用它吧!

创建形状

我们将通过创建一个地板平面来开始我们的基础。我们将通过以下方式来做到这一点:

  1. 打开 ProBuilder 并转到工具 | ProBuilder | ProBuilder窗口:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.24 - ProBuilder 窗口选项

  1. 在打开的窗口中,单击New Shape按钮右侧的加号图标(+):外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.25 - 新形状选项

  1. Shape Selector中,选择Plane

  2. 设置50

  3. 设置2。我们稍后会需要这些细分:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.26 - 新形状设置

  1. 单击Build按钮以确认Plane

  2. 单击场景视图中ProBuilder按钮中的四个按钮中的第一个按钮,以启用整个平面的移动:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.27 - 选择对象工具

  1. 用这个地板替换占位符立方体:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.28 - 平面被细分为 3 x 3 网格

既然我们已经创建了地板,让我们学习如何操纵其顶点以改变其形状。

操纵网格

如果您选择平面,您会看到它被细分为 3 x 3 网格,因为我们将宽度和高度分段设置为 2(2 切割)。我们这样做是因为我们将使用外部单元来创建我们的墙,从而将它们升起。我们的想法是修改这些单元的大小,以勾勒出墙的长度和宽度,然后再创建墙。为了做到这一点,我们将执行以下操作:

  1. 选择平面。

  2. 单击场景视图中出现的四个新按钮中的第二个按钮(显示顶点):外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.29 - 选择顶点工具

  1. 单击并拖动鼠标以创建一个选择框,选择第二行顶点的四个顶点:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.30 - 顶点选择

  1. 单击 Unity 编辑器顶部左侧的第二个按钮,以启用移动工具:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.31 - 移动工具

  1. 移动顶点行,使平面的这个细分变得更薄。您可以使用地形上的方格图案来了解墙的尺寸:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.32 - 移动顶点

  1. 重复步骤 35,直到您获得具有相似大小的墙轮廓:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.33 - 移动顶点以减少边缘单元宽度

重要提示

如果您希望顶点具有精确的位置,我建议您安装并探索 ProGrids 包。这是一个与常规 Unity 和 ProBuilder 一起使用的位置捕捉系统。

现在我们已经为墙壁创建了轮廓,让我们向网格添加新的面来创建它们。为了使用我们创建的细分或“面”来制作墙壁,我们必须选择并拉伸它们。按照以下步骤进行:

  1. 选择平面。

  2. 在场景视图中选择ProBuilder按钮的第四个按钮:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.34 – 选择面工具

  1. 在按住Ctrl(Mac 上为command)的同时,单击墙壁轮廓的每个面:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.35 – 选择边缘面

  1. ProBuilder窗口中,找到Extrude Faces按钮右侧的加号图标(+)。它将位于窗口的红色部分:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.36 – 拉伸面选项

  1. 在点击加号按钮后出现的窗口中设置5

  2. 单击该窗口中的Extrude Faces按钮:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.37 – 拉伸距离选项

  1. 现在,你应该看到墙壁的轮廓刚从地面上升起:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.38 – 拉伸的网格边缘

现在,如果你注意一下基础地板和墙壁与地形的接触,会发现有一点间隙。我们可以尝试将基础向下移动,但地板可能会消失,因为它将被埋在地形下面。我们可以在这里做一个小技巧,只是将墙壁向下推,而不移动地板,这样墙壁将被埋在地形中,但我们的地板将保持与地形的一点距离。你可以在以下图中看到它看起来的样子:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.39 – 预期结果的切片

为了这样做,我们需要执行以下操作:

  1. 在场景视图中选择第三个ProBuilder按钮以启用边缘选择:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.40 – 选择边缘工具

  1. 在按住Ctrl(Mac 上为command)的同时,选择墙壁的所有底部边缘。

如果选择了不想要的边缘,只需再次单击它们,同时按住Ctrl(Mac 上为command)取消选择,同时保持当前选择:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.41 – 选择地板边缘

信息框

如果你想在上一个截图中使用线框模式,点击场景视图左上部的着色按钮,并从下拉菜单中选择线框选项。

  1. 启用移动工具,按下 Unity 编辑器左上部的第二个按钮:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.42 – 移动工具

  1. 将边缘向下移动,直到完全埋在地形下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.43 – 重叠的面

现在我们有了一个基础网格,我们可以开始使用其他几个 ProBuilder 工具向其添加细节。

添加细节

让我们开始通过对墙壁施加一点倒角来向基础添加细节。按照以下步骤进行:

  1. 使用边缘选择模式(ProBuilder按钮的第三个按钮),选择我们模型的顶部边缘:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.44 – 选择顶部墙壁边缘

  1. ProBuilder窗口中,点击Bevel按钮右侧的加号图标。

  2. 设置距离为0.5外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.45 – 生成倒角距离

  1. 点击Bevel Edges。现在,你可以看到我们墙壁的顶部有一点倒角:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.46 – 倒角过程的结果

  1. 可选地,你也可以对内墙的底部进行操作:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.47 - 地板-墙壁边缘应用斜角

另一个要添加的细节可能是地面中央的坑,作为我们需要避免掉入的危险,以及使敌人避开它使用人工智能。为了做到这一点,请按照以下步骤操作:

  1. 点击第四个 ProBuilder 场景视图按钮,启用 FACE 选择模式。

  2. 选择地板。

  3. 在 ProBuilder 窗口中点击Subdivide面选项。你将得到地板分成四块。

  4. 再次点击该按钮,以得到一个 4x4 的网格地板:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.48 - 细分地板

  1. 选择四个内部地板砖。

  2. 通过点击 Unity 编辑器左上角的第四个按钮,启用缩放工具:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.49 - 缩放工具

  1. 使用标尺中心的灰色立方体,缩小中心的瓷砖:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.50 - 内部单元格被缩小

  1. ProBuilder窗口中点击 Extrude Faces 按钮。

  2. 将挤出的面向下推。

  3. 右键单击ProBuilder窗口标签,然后选择Close Tab。我们需要回到地形编辑,并且ProBuilder打开会让我们无法舒适地进行编辑:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.51 - 关闭标签选项

  1. 选择地形并降低该地区的地形,以便我们可以看到坑:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4.52 - 为了使坑可见而降低地形

我知道我们在原始关卡布局中没有计划这个坑,但请记住,定义首字母缩写是一个在游戏开发中会不断变化的文件,所以有时候,我们可以大胆地进行更改,以改进游戏。只是要注意不要过度进行永无止境的更改,这是一门难以掌握的艺术。

总结

在本章中,我们学习了如何使用高度图和 Unity 地形工具创建大型地形网格,例如使用绘制高度和设置高度来创建山丘和河流盆地。此外,我们还学习了如何使用 ProBuilder 创建自己的 3D 网格,以及如何操纵模型的顶点、边和面,创建游戏原型基础模型。我们没有讨论一些可以应用于网格的性能优化,或者一些高级的 3D 建模概念,因为那需要整整的章节,而这超出了本书的范围。现在,我们的主要重点是原型设计,所以我们对我们关卡的当前状态感到满意。

在下一章中,我们将学习如何使用外部工具创建的资产(文件)来下载和替换这些原型模型。这是提高游戏图形质量的第一步,以便达到最终的外观,这将在第二部分结束时完成。

第五章:导入和整合资产

在上一章中,我们创建了我们的关卡的原型。现在,假设我们已经编写了游戏并对其进行了测试,验证了这个想法。因此,现在是时候将原型艺术改为真正的完成艺术了。实际上,我们将在第三部分编写游戏,但出于学习目的,让我们暂时跳过这部分。为了使用最终资产,我们需要学习如何获取它们(图像、3D 模型等),如何将它们导入 Unity,并如何在我们的场景中使用它们。

在本章中,我们将研究以下主题:

  • 导入资产

  • 整合资产

  • 配置资产

导入资产

我们可以在项目中使用不同的资产来源。我们可以简单地从我们的艺术家那里获取文件,从不同的免费和付费资产网站下载它们,或者我们可以使用资产商店,Unity 的官方虚拟资产商店,在那里我们可以获取准备在 Unity 中使用的免费和付费资产。我们将使用从互联网和资产商店下载资产的混合方式,以获取所有可能的资源。

在本节中,我们将涵盖与导入资产相关的以下概念:

  • 从互联网导入资产

  • 从资产商店导入资产

  • 从互联网下载并导入我们项目中的资产

从互联网导入资产

在获取项目的艺术资产方面,让我们从地形纹理开始。请记住,我们的地形上有一个网格图案,所以想法是用草、泥土、岩石和其他类型的纹理替换它。为此,我们必须获取图像。在这种情况下,这些图像通常是不同地形图案的俯视图,并且它们必须是“可平铺的”。您可以在以下截图中看到一个示例:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 5.1 – 左:草块;右:将同一草块分开以突出纹理平铺

左边的草看起来是一个单一的大图像,但如果您留意,应该能够看到一些重复出现的图案。在这种情况下,这种草只是一个在网格中重复四次的单个图像,就像右边的那个。这样,您可以通过重复单个小图像来覆盖大面积,从而节省计算机内存。

想法是获取这些类型的图像来绘制我们的地形。你可以从几个地方获取它们,但最简单的方法是使用 Google 图片或任何图片搜索引擎。要做到这一点,请按照以下步骤操作:

  1. 打开您的浏览器(Chrome、Safari、Edge 等)。

  2. 转到您喜欢的搜索引擎。在这种情况下,我将使用 Google。

  3. 使用关键词PATTERN tileable texture,将PATTERN替换为您正在寻找的地形类型,例如grass tileable texturemud tileable texture。在这种情况下,我将输入grass tileable texture,然后按Enter进行搜索。

  4. 切换到图像搜索模式:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 5.2 – Google 图像搜索

  1. 找到任何您认为适合所需草坪的纹理并单击它。请记住,纹理必须是草的俯视图,并且必须重复。

重要提示

在选择图像之前,请尝试检查图像的分辨率。现在,请尝试选择分辨率小于 1024 x 1024 的正方形图像。

  1. 右键单击打开的图像,然后选择另存为图像…外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 5.3 – 另存为图像…选项

  1. 将图像保存在您记得的任何文件夹中。

现在您已经下载了图像,可以通过几种方式将其添加到您的项目中。最简单的方法是执行以下操作:

  1. 使用文件资源管理器(Mac 中的Finder)找到您的图像。

  2. 在 Unity 的项目窗口中找到或创建Textures文件夹。

  3. 将文件资源管理器和 Unity 项目窗口并排放置。

  4. 将文件从文件资源管理器拖到 Unity 项目窗口的Textures文件夹中:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 5.4 - 从文件资源管理器拖动纹理到 Unity 项目视图

对于这些简单的纹理,任何搜索引擎都可以帮助,但如果你想用详细的墙壁和门替换玩家的基础几何图形,或者在场景中放置敌人,你需要获取 3D 模型。如果你使用关键词如“免费僵尸 3D 模型”在任何搜索引擎中搜索,你会找到无数的免费和付费 3D 模型网站,如 TurboSquid 和 Mixamo,但这些网站可能存在问题,因为这些网格通常没有准备好在 Unity 中使用,甚至在游戏中使用。你会发现模型的多边形数量非常高,尺寸或方向不正确,纹理未经优化等等。为了避免这些问题,我们需要使用更好的来源,在这种情况下,我们将使用 Unity 的资产商店,所以让我们来探索一下。

从资产商店导入资产

资产商店是 Unity 的官方资产市场,你可以在那里找到很多模型、纹理、声音,甚至整个 Unity 插件,以扩展引擎的功能。在这种情况下,我们将限制自己下载 3D 模型来替换玩家的基础原型。你会想要获取模块化设计的 3D 模型,意味着你会得到几个部分,如墙壁、地板、角落等等。你可以连接它们来创建任何类型的场景。

为了做到这一点,你必须按照以下步骤进行:

  1. 在 Unity 中点击窗口|资产商店,这将打开一个新窗口,显示资产商店已经移动。在之前的 Unity 版本中,你可以直接在编辑器中看到资产商店,但现在建议在常规网络浏览器中打开它,所以只需点击在线搜索按钮:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 5.5 - 资产商店已移动消息

  1. 你的浏览器将打开一个类似于以下截图的网站:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 5.6 - 资产商店首页

  1. 在右侧面板中,点击其右侧的箭头打开 3D 类别。然后,打开环境并勾选科幻标记。如你所见,有几个类别可以找到不同类型的资产,如果你愿意,你可以选择另一个。在环境中,你会找到可以用来生成游戏场景的 3D 模型。

  2. 如果需要的话,你可以为资产付费,但现在让我们先隐藏付费的资产。你可以通过侧边栏的定价部分进行搜索,使用其右侧的加号(+)符号打开它,然后勾选免费资产复选框:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 5.7 - 免费资产选项

  1. 在搜索区域,找到任何看起来具有你所寻找美学的资产,并点击它。记得留意户外资产,因为大多数环境包通常只有室内。在我的情况下,我选择了一个名为科幻风格模块化包的资产,它适用于室内和室外。请注意,到你阅读本书时,该包可能已经不存在,所以你可能需要选择另一个。如果你找不到合适的包,你可以下载我们在 GitHub 存储库中使用的资产文件。请参考如何访问它的前言说明。外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 5.8 - 资产商店搜索包的预览

重要提示

在撰写本书时,Unity 正在发布“Snaps”包,这是一组官方 Unity 3D 模型,可用于不同类型环境的模块化设计。其中一些是付费的,而另一些是免费的 - 我建议你试试看。

  1. 现在,你将在资产商店窗口中看到包的详细信息。在这里,你可以找到关于包的描述、视频/图片、包的内容,以及最重要的部分,评论,你可以查看包是否值得购买,如果是付费的话:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 5.9 – 资产商店包详情

  1. 如果你对这个包满意,点击添加到我的资产按钮,如果需要的话登录 Unity,然后点击在 Unity 中打开按钮。你可能会被提示接受切换到 Unity 应用程序 – 只需接受:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 5.10 – 切换应用程序

  1. 这将再次打开包管理器,但这次是以我的资产模式,显示你从资产商店下载过的所有资产的列表,以及你刚刚在列表中选择的那个被突出显示的资产。如果你没有在 Unity Hub 中登录,你可能需要点击登录按钮重新登录 Unity。外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 5.11 – 包管理器显示资产

  1. 点击窗口右下角的下载,等待下载完成。然后点击导入。双重检查你是否从列表中选择了正确的资产包。

  2. 过了一会儿,包内容 窗口将会出现,允许你选择包中的哪些资产要放入你的项目中。现在,保持原样,点击导入外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 5.12 – 要导入的资产

  1. 一段时间后导入,你将在项目窗口中看到所有的包文件。

请注意,导入大量完整的包将大大增加你项目的大小,而且以后你可能想要删除你没有使用的资产。另外,如果导入的资产生成了错误,阻止你播放场景,只需删除包中附带的所有.cs文件。它们通常在名为Scripts的文件夹中。这些是可能与你的 Unity 版本不兼容的代码文件。在第三部分中,我们将学习如何制作我们自己的,这样就不需要这些了:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 5.13 – 点击播放时的代码错误警告

重要提示

资产商店容易发生变化,即使你使用的是和我一样的 Unity 版本,所以之前的步骤可能会被 Unity 改变而没有通知。而且,它的内容经常变化,你可能找不到本书中使用的相同的包。在这种情况下,你可以找到另一个类似的包,或者从 GitHub 仓库中获取我使用的文件(在前言中有链接和说明)。

在继续本章之前,尝试使用资产商店下载一个敌人角色,按照之前的步骤。为了解决这个练习,你必须完成之前的相同步骤,但是在资产商店的3D | 人物 | 人形类别中查找。

现在我们已经导入了大量的艺术资产,让我们学习如何在场景中使用它们。

整合资产

我们刚刚导入了许多可以以多种方式使用的文件,所以这一部分的目的是看看 Unity 如何将这些资产与需要它们的游戏对象和组件整合在一起。

在本节中,我们将涵盖与导入资产相关的以下概念:

  • 整合地形纹理

  • 整合网格

  • 整合材质

让我们开始使用平铺纹理来覆盖地形。

整合地形纹理

为了将纹理应用到我们的地形,做如下操作:

  1. 选择地形对象。

  2. 检视器中,点击地形组件的刷子图标(第二个按钮)。

  3. 从下拉菜单中选择油漆纹理外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 5.14 – 油漆纹理选项

  1. 点击编辑地形层… | 创建层选项。

  2. 在纹理选择器窗口中查找之前下载的地形纹理:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 5.15-纹理选择器

  1. 您将看到纹理将立即应用于整个地形。

  2. 重复步骤 45来添加其他纹理。这一次,您会发现该纹理不会立即应用。

  3. 地形层部分,选择您创建的新纹理开始绘制。在我的案例中,我使用了泥浆纹理。

  4. 就像编辑地形时,在画笔部分,您可以选择并配置一个画笔来绘制地形。

  5. 在场景视图中,绘制您希望应用该纹理的区域。

  6. 如果您的纹理图案太明显,选择地形层框中的纹理,然后打开NewLayer N,其中 N 是您创建的层数所依赖的数字。

重要提示

每次向地形添加纹理,您会看到在项目视图中创建了一个名为“NewLayer N”的新资产。它保存了您创建的地形层的数据,如果需要,您可以在其他地形中使用它。您还可以重命名该资产以赋予其有意义的名称。此外,您还可以将这些资产重新组织到它们自己的文件夹中。

  1. 使用左侧的三角形打开该部分,并在平铺设置部分中增加大小属性,直到找到一个合适的大小,其中图案不那么明显:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 5.16-绘画纹理选项

  1. 重复步骤 412,直到您应用了所有想要添加到地形的纹理。在我的案例中,我将泥浆纹理应用于河流盆地,并在山丘上使用了岩石纹理。对于岩石的纹理,我减少了画笔的不透明度属性,以更好地与山上的草地融合。您可以尝试在顶部添加一层雪,只是为了好玩:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 5.17-用三种不同的纹理绘制我们的地形的结果

当然,我们可以使用系统的许多高级工具来大大改进这一点,但让我们现在保持简单。现在,让我们看看如何集成 3D 模型。

集成网格

如果您选择我们之前配置过的 3D 资产之一并单击其右侧的箭头,则一个或多个子资产将出现在项目窗口中。这意味着 FBX 不是一个 3D 模型,而是定义 3D 模型的资产容器:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 5.18-网格选择器

其中一些子资产是网格,这是定义模型几何形状的三角形集合。您可以在文件中找到至少一个这样的网格,但也可以找到多个,如果您的模型由许多部分组成,那就可能会发生。例如,汽车可以是一个单一的刚性网格,但这不允许您旋转其车轮或打开其车门;它只是一个静态的汽车,如果汽车只是场景中的道具,那可能足够了,但如果玩家能够控制它,您可能需要对其进行修改。这个想法是您的汽车的所有部分都是不同的游戏对象,彼此之间是父子关系,这样如果您移动一个,所有的都会移动,但您仍然可以独立旋转这些部分。

当您将 3D 模型文件拖到场景中时,Unity 将根据艺术家的创建方式自动为每个部分创建所有对象及其适当的父子关系。您可以在层次结构中选择对象并探索其所有子对象来查看这一点:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 5.19-子对象选择

此外,您会发现每个对象都有自己的MeshFilterMeshRenderer组件,每个组件只渲染汽车的一部分。请记住,网格过滤器是一个具有对要渲染的网格资产的引用的组件,因此网格过滤器是使用我们之前讨论过的那些网格子资产的组件:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 5.20 – 网格过滤器当前网格选择

现在,如果您将 3D 模型文件拖入场景,您将获得与模型为 Prefab 且您正在实例化它时类似的结果。但是 3D 模型文件比 Prefab 更有限,因为您无法对模型应用更改,因此在将对象拖入场景并编辑以获得所需的行为后,我建议您创建一个 Prefab,以获得我们在第三章中讨论的所有好处,使用场景和游戏对象,例如对所有 Prefab 实例应用更改等。永远不要从模型文件创建大量实例 – 总是从基于该文件创建的 Prefab 创建它们。

这是 3D 网格的基本用法。现在,让我们来探讨纹理集成过程,这将使我们的 3D 模型更加详细。

集成纹理

也许您的模型已经应用了纹理,或者它已经应用了品红色。在后一种情况下,这意味着该资产未准备好与您在创建项目时选择的 URP 模板一起使用。Asset Store 中的一些资产是为旧版本的 Unity 而设计的:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 5.21 – 使用错误或没有材质渲染的网格

修复的一个选项是使用编辑 | 渲染管线 | 通用渲染管线 | 将项目材质升级到 UniversalRP 材质。这将尝试将所有材质升级到 Unity 的当前版本:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 5.22 – 将材质升级到 URP

这种方法的缺点是,有时它无法正确升级材质。幸运的是,我们可以通过以这种新方式重新应用对象的纹理来解决这个问题。即使您的资产工作正常,我建议您无论如何重新应用纹理,只是为了更多地了解材质的概念。

纹理直接应用于对象。这是因为纹理只是控制模型外观的所有配置中的一个。为了改变模型的外观,您必须创建一个材质。材质是一个单独的资产,包含有关 Unity 应该如何渲染您的对象的许多设置。您可以将该资产应用于共享相同图形设置的多个对象,如果更改材质的设置,它将影响使用它的所有对象。它的工作原理类似于图形配置文件。

为了创建一个可以应用纹理的材质,您需要按照以下步骤进行:

  1. 在项目窗口中,单击窗口左上角的加号(+)按钮。

  2. 在菜单中找到Material选项并单击它。

  3. 给您的材质命名。这通常是您正在创建的资产的名称(例如,汽车,船,角色等)。

  4. 将您创建的材质资产拖到场景中的模型实例上。目前,如果您将鼠标与拖动的资产一起移动到对象上,您将能够预览使用该材质的外观。释放鼠标即可确认。

  5. 也许您的对象有几个部分。在这种情况下,您需要将材质拖到对象的每个部分。

重要提示

拖动材质只会改变您拖动的对象的MeshRenderer组件的材质属性。

  1. 选择材质并单击Base Map属性左侧的圆圈。

  2. 纹理选择器中,点击模型的纹理。定位纹理可能有些复杂。通常,纹理的名称将与模型名称匹配。如果不匹配,您将需要尝试不同的纹理,直到找到适合您对象的纹理。此外,您可能会发现几个与您的模型同名的纹理。只需选择看起来颜色合适的纹理,而不是看起来是黑白或浅蓝色的纹理;我们稍后会用到它们:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 5.23 – URP 材质的基本贴图属性

通过这样,您已成功通过材质将纹理应用到对象上。对于每个使用相同纹理的对象,只需拖动相同的材质。现在我们已经基本了解了如何应用模型纹理,让我们学习如何在将模型传播到整个场景之前正确配置导入设置。

配置资产

正如我们之前提到的,艺术家习惯于在 Unity 之外创建艺术资产,这可能导致从该工具中看到的资产与 Unity 导入的方式之间存在差异。例如,3D Studio 可以使用厘米、英寸等单位,而 Unity 使用米。我们刚刚下载并使用了大量资产,但我们跳过了解决这些差异的配置步骤,所以现在让我们来看看这个。

在本节中,我们将涵盖与导入资产相关的以下概念:

  • 配置网格

  • 配置纹理

让我们开始讨论如何配置 3D 网格。

配置网格

为了更改模型的导入设置,您需要定位您下载的模型文件。包含 3D 模型的文件扩展名有几种,最常见的是.fbx文件,但您可能会遇到其他扩展名,如.obj.3ds.blender.mb等。您可以通过其扩展名来识别文件是否为 3D 网格:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 5.24 – 选择的资产路径扩展

此外,您可以点击资产,并在检查器中查看以下截图中可以看到的选项卡:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 5.25 – 网格材质设置

现在您已经找到了 3D 网格文件,可以正确配置它们。现在,我们应该考虑的唯一事情是模型的适当比例。艺术家习惯于使用不同设置的不同软件工作;也许一个艺术家使用米作为其度量单位创建了模型,而其他艺术家使用英寸、英尺等。当导入使用不同单位创建的资产时,它们可能会不成比例,这意味着我们将得到诸如人类比建筑物更大等结果。

最好的解决方案是询问艺术家来解决这个问题。如果所有的资产都是由您公司创建的,或者您使用了外部资产,您可以要求艺术家将其修复为您公司的工作方式,但现在,您可能是一个独立学习 Unity 的开发人员。幸运的是,Unity 有一个设置,允许您在在 Unity 中使用原始资产之前重新调整其比例。为了改变对象的比例因子,您必须执行以下操作:

  1. 在项目窗口中找到 3D 网格。

  2. 将其拖到场景中。您会看到一个对象出现在您的场景中。

  3. 使用GameObject | 3D Object | Capsule选项创建一个胶囊。

  4. 将胶囊放在您拖入编辑器的模型旁边。看看比例是否合理。这样做的目的是让胶囊代表一个人(2 米高),这样您就有了比例的参考:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 5.26 – 不成比例的资产

  1. 如果模型比预期的要大或小,请在项目窗口中再次选择网格(而不是您拖到编辑器中的 GameObject 实例),您将在检查器中看到一些导入设置。

  2. 查找比例因子属性并修改它,如果您的模型比预期的要小,则增加它,或者在相反的情况下减小它:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 5.27-模型网格选项

  1. 单击检查器底部的应用按钮。

  2. 重复步骤 67,直到获得所需的结果。

还有很多其他选项要配置,但现在让我们暂停一下。现在,让我们讨论如何正确配置我们模型的纹理。

配置纹理

同样,这里有几个设置要配置,但让我们现在专注于纹理大小。想法是使用最适合该纹理使用的大小,这取决于许多因素。要考虑的第一个因素是从对象将被看到的距离。如果您正在创建第一人称游戏,您可能会看到足够接近的许多对象,以证明大纹理的必要性,但也许您有许多远处的对象,例如建筑物顶部的广告牌,您永远不会靠近到足以看到细节,因此您可以为此使用较小的纹理。还要考虑的是对象的重要性。如果您正在创建赛车游戏,您可能会有许多只会在屏幕上出现几秒钟且玩家永远不会关注的 3D 模型;他们将会注意道路和其他汽车。在这种情况下,街上的垃圾箱之类的对象可以有一个小纹理和低多边形模型,用户永远不会注意到(除非他们停下来欣赏风景,但这是可以接受的)。最后,您可以有一个从顶部向下查看的游戏,永远不会放大场景,因此在第一人称游戏中具有大纹理的相同对象在这里会有一个不太详细的纹理。在下一张图中,您可以看到较小的船可以使用较小的纹理:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 5.28-在不同距离下看到相同的模型

纹理的理想尺寸是相对的。找到它的常规方法是通过改变其大小,直到在游戏中以可能的最近位置看到对象时找到最小可能的尺寸并保持良好的质量。这是一种反复试验的方法。为了做到这一点,您可以执行以下操作:

  1. 找到 3D 模型并将其放入场景中。

  2. 将场景视图相机放置在一个位置,以便以游戏中最大的尺寸显示对象。例如,在 FPS 游戏中,它几乎会在对象旁边,而在俯视游戏中,它会在对象上方几米处。同样,这取决于您的游戏。

  3. 在导入包或之前创建的材质中的文件夹中找到并选择对象使用的纹理。它们通常具有.png.jpg.tif扩展名。

  4. 在检查器中,查看最大尺寸属性并减小它,尝试下一个更小的值。例如,如果纹理为 2,048,请尝试 1,024。

  5. 单击应用并检查场景视图,看看质量是否急剧下降或更改是否不明显。您会感到惊讶。

  6. 重复步骤 45,直到获得低质量的结果。在这种情况下,只需增加先前的分辨率以获得可接受的质量。当然,如果您的目标是 PC 游戏,您可以期望比移动游戏更高的分辨率。

现在您已经导入,集成和配置了您的对象,让我们用这些资产创建我们的玩家基地。

组装场景

让我们开始使用我们下载的环境包替换我们的原型基地。为此,您必须执行以下操作:

  1. corner关键字中:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 5.29 - 网格选择器

  1. 在我的特定情况下,我有角落的外侧和内侧作为单独的模型,所以我需要将它们放在一起。

  2. 将其放置在原型基地的任何一个角落的相同位置:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 5.30 - 在替换占位符上放置网格

  1. 找到适合与角落连接以创建墙壁的合适模型。同样,你可以尝试在项目窗口中搜索wall关键字。

  2. 实例化它并将其定位,使其与角落相连。如果不完全匹配,不要担心;以后可以随时调整场景。

重要提示

你可以选择一个对象,按下V键选择所选对象的顶点,将其拖动到另一个对象的顶点。这被称为顶点捕捉。它允许你精确地连接场景中的两个部分:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 5.31 - 连接两个模块

  1. 重复墙壁,直到达到玩家基地的另一端,并放置另一个角落。你可能会得到一个比原型稍大或稍小的墙壁,但没关系:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 5.32 - 连接模块的链

重要提示

记住,你可以按住Ctrl键(Mac 上的Control)移动一个对象,以便将对象的位置捕捉到墙壁的克隆物可以轻松地定位在其他墙壁旁边。

  1. 完成其余的墙壁并摧毁原型。记住这个过程很慢,你需要耐心。

  2. 通过寻找地板砖并在整个表面重复它们来添加地板:!图 5.33 - 带有坑洞的地板模块

图 5.33 - 带有坑洞的地板模块

  1. 使用包中的其他模块化部件添加任何你想要添加的细节。

  2. 将所有这些部件放入一个名为Base的容器对象中。记得创建一个空对象,然后将基础部件拖放到其中:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 5.34 - 网格子资产

经过多次练习,你将慢慢积累关于模块化场景设计的常见问题和良好实践的经验。所有的包都有不同的模块化设计,所以你需要适应它们。

总结

在本章中,我们学习了如何导入模型和纹理,并将它们整合到我们的场景中。我们讨论了如何将纹理应用到地形上,如何用模块化模型替换我们的原型网格,如何将纹理应用到这些模型上,以及如何根据对象的使用情况考虑多个标准来正确配置资产。

通过这样,我们已经完成了本书的第一部分,并讨论了几个基本的 Unity 概念。在第二部分中,我们将开始深入研究几个 Unity 系统,这些系统可以帮助我们改善游戏的图形和声音质量。我们将开始学习如何创建自定义材质类型,以创建有趣的视觉效果和动画。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值