< Return to Video

The Unity Tutorial For Complete Beginners

  • 0:00 - 0:06
    嗨,我叫马克。多年来,我一直想用软件制作我自己的视频游戏。
  • 0:06 - 0:13
    比如 Unity。Unity 是很多游戏背后强大的游戏引擎,包括:Cuphead、Neon White、Tunic
  • 0:13 - 0:19
    Outer Wilds,炉石传说,看火者,甚至口袋妖怪钻石重制版。
  • 0:19 - 0:26
    但我总是发现,太长的、各式各样的、弯的教程只会让我睡死过去。
  • 0:26 - 0:31
    我不可能三连收藏就假装会了,必须亲自动手啊,自己写bug才行。
  • 0:31 - 0:38
    所以去年我发明了一个实际可行的步骤,叫三步(三连?)技巧。
  • 0:38 - 0:45
    第一,只需要学习 Unity 的非常非常基础的知识。第二,用简单的方法巩固这些练习
  • 0:45 - 0:51
    然后,第三,在你前进的过程中解决剩下的bug。这绝逼有用!
  • 0:51 - 0:57
    在大约一年的时间里,我从借鉴 iPhone 游戏到开发自己的平台解谜游戏
  • 0:57 - 1:03
    游戏名:Magnets。我发布了一篇互动视频,已经有超过 10 万次播放
  • 1:03 - 1:09
    但是这些人看完总是问!第一步你怎么做?Unity这个软件太复杂了
  • 1:09 - 1:12
    你是如何学习基础知识的?
  • 1:12 - 1:15
    嗯,所以说,我就列了一份清单
  • 1:15 - 1:20
    不管我要做什么游戏,比如如何显示一个角色
  • 1:20 - 1:24
    在屏幕上移动它们。如何生成一个东西,然后再次移除它
  • 1:24 - 1:29
    然后,碰撞怎么搞,游戏结束呢,动画和声音效果等。
  • 1:29 - 1:34
    然后我通过搜索学不完的教程,还有 Unity 文档,
  • 1:34 - 1:37
    在谷歌上搜索深奥的关键词,并大量的测试和出现bug
  • 1:37 - 1:42
    这段视频的重点就是帮你省去这些麻烦。
  • 1:42 - 1:46
    这个视频是我在学习 Unity 时就希望拥有的教程。
  • 1:46 - 1:52
    所以在接下来的 40 分钟里,我们将使用引擎来制作 Flappy Bird.
  • 1:52 - 1:57
    不是因为我们想制作Flappy Bird,而是重做这款令人上瘾的 iPhone 游戏
  • 1:57 - 2:02
    我们会学习到刚才列出的所有内容,从生成对象到游戏结束。
  • 2:02 - 2:08
    本教程将涵盖从下载 Unity 到理解 UI 的每一步。
  • 2:08 - 2:14
    去写你的第一行编程代码,去构建一个你可以分享的游戏
  • 2:14 - 2:19
    你的朋友。然后,当教程结束时,我将分享一些具体的后续步骤,你可以
  • 2:19 - 2:26
    以便自己继续学习更多内容。听起来阔以吧?那就开始吧。
  • 2:27 - 2:34
    好的,让我们从网站上获取 Unity 开始。下载并安装 Unity Hub.
  • 2:35 - 2:40
    然后你需要创建一个免费帐户才能真正使用它。
  • 2:40 - 2:46
    完成后,你将被要求安装 Unity 编辑器,本教程中使用的是 2021.3 版本。
  • 2:46 - 2:49
    都2022年了,怎么还跟原始社会一样的,
  • 2:49 - 2:52
    网络慢的跟屎一样
  • 2:52 - 3:00
    还没完成,在“安装”下,点击 Unity 编辑器上的 ... 图标并选择模块。
  • 3:00 - 3:05
    你将看到 Microsoft Visual Studio 已被勾选,这是写代码的软件。
  • 3:05 - 3:11
    所以点击继续。并安装 Visual Studio.
  • 3:11 - 3:15
    在这个屏幕上,向下滚动并勾选 Unity 游戏开发,然后取消勾选 Unity Hub.
  • 3:15 - 3:20
    因为我们已经有了,我们不需要创建帐户来使用 VisualStudio,
  • 3:20 - 3:24
    所以跳过那个。不用加载了,我们稍后再打开。
  • 3:24 - 3:31
    好了,现在都搞完了。在 Unity Hub 中,选择新项目。选择所有模板。且使用 2D Core
  • 3:31 - 3:36
    这是一个空的项目,需要做些配置才比较适合 2D 游戏。
  • 3:36 - 3:41
    给你的项目命名,点击创建,让我们开始游戏制作。
  • 3:43 - 3:49
    第一步,我们将熟悉默认的 Unity 用户界面。
  • 3:49 - 3:52
    当熟悉不同的面板时,我们将顺便显示一只鸟在屏幕上。
  • 3:52 - 3:59
    好,这是 Unity 的默认屏幕布局,它分为四个面板。
  • 4:00 - 4:05
    首先,这里是项目面板。这将包含我们游戏中的所有内容。
  • 4:05 - 4:13
    -如精灵,声音效果,脚本,瓷砖,字体等。使用过程有些东西会被生成出来。
  • 4:13 - 4:18
    不过我们也可以从电脑上的其他地方拖进一些需要文件。
  • 4:18 - 4:23
    比如,我在 Photoshop 中制作了小鸟和烟斗的图片
  • 4:23 - 4:28
    就像这样将它们导入到我的项目中。我建议你别光看,最好做一下,顺便三连。
  • 4:28 - 4:32
    但如果你有毫无绘画天赋,去视频简介里拿这些资源吧。
  • 4:32 - 4:39
    下一个面板是层次结构。这包含了当前场景中的所有内容,
  • 4:39 - 4:43
    在大多数游戏中,叫关卡也可。我们将从制作鸟开始,
  • 4:43 - 4:50
    因此,右键单击并选择“创建 Empty”。创建了一个空的游戏对象..是什么鬼呢?
  • 4:50 - 4:57
    嗯,游戏对象本质上是一个看不见的容器。它在空间中有一个位置,一个旋转,
  • 4:57 - 5:03
    和缩放。然后,你可以用组件填充该容器-以添加额外的功能。
  • 5:03 - 5:08
    例如,如果我们添加一个精灵渲染器(SpriteRenderer)组件,
    我们可以将鸟的图像放到游戏对象上。
  • 5:08 - 5:13
    当然,我们关卡中的东西都是一个带有组件的游戏对象,
  • 5:13 - 5:16
    不管是鸟啊,管道啊,甚至用户界面和摄像头,都是这种一个对象有多个组件。
  • 5:16 - 5:23
    最后在第三个面板中,即检查器(Inspector)——用于查看和配置游戏对象的属性。
  • 5:23 - 5:28
    所以,当我们选中了一个新的对象,空的游戏对象,我们就可以在顶部修改名称-比如:Bird
  • 5:28 - 5:35
    我们可以看到 Transform 这里可以改变游戏对象的位置,旋转和缩放。
  • 5:35 - 5:42
    现在,我们可以按“添加组件”、“拾取渲染”和“拾取精灵渲染器”。为了实现这一点,
  • 5:42 - 5:46
    我们需要填充 sprite 字段-因此只需将鸟图像从
  • 5:46 - 5:50
    项目面板把它拖进来这里,这样就有图片显示出来了!
  • 5:50 - 5:53
    当然,这将在第四个也是最后一个面板中显示,
  • 5:53 - 5:57
    场景视图。在这里,我们可以看到当前场景中的内容,
  • 5:57 - 6:02
    如果你愿意,你可以使用这些工具来移动东西,缩放它,等等。
  • 6:02 - 6:07
    这个部分有一个额外的游戏视图标签,它向我们展示了游戏的外观。
  • 6:07 - 6:13
    运行时的主摄像头。此外,从这个下拉菜单中,我们可以设置分辨率或屏幕比例
  • 6:13 - 6:19
    为了更好地了解它在播放时的样子,所以我将选择 1920 乘以 1080。
  • 6:19 - 6:24
    哦,这只鸟占据了太多的空间。我们可以缩小规模,但实际上
  • 6:24 - 6:30
    把镜头拉远。就像我之前说的,摄影机本身就是层次结构中的一个游戏对象。
  • 6:30 - 6:36
    它有一个摄像头组件,里面有我们可以调整的属性。通过改变大小,我们可以缩小。
  • 6:36 - 6:39
    我也要改变背景颜色,搞个可爱的。
  • 6:39 - 6:44
    我们现在可以按下上面的播放按钮开始..
  • 6:44 - 6:48
    世界上最无聊的游戏诞生了。好吧,让我们把它变得更刺激一点。
  • 6:49 - 6:55
    快速回顾一下。默认情况下,Unity 有四个面板。项目包含我们的所有游戏内容
  • 6:55 - 7:01
    层次列出了当前级别中的所有游戏对象。检视器(Inspector)让我们看看。
  • 7:01 - 7:05
    并更改这些游戏对象。我们可以在场景视图中看到级别。
  • 7:05 - 7:11
    游戏对象是一个不可见的容器,我们可以用组件填充它,就像精灵渲染器一样。
  • 7:12 - 7:16
    在第二步中,我们将使用更多的组件将鸟变成
  • 7:16 - 7:19
    受重力影响的物理对象。然后我们要写一些编程代码,
  • 7:19 - 7:23
    让小鸟在我们按下空格键的时候飞起来。
  • 7:23 - 7:30
    所以让我们给我们的鸟添加另一个组件:一个2D刚体(Rigidbody2D) .
  • 7:30 - 7:37
    这把我们的鸟变成了物理物体,有重力。所以当我们点击播放时,鸟就会掉下来,从屏幕上掉下来,凉凉了。
  • 7:37 - 7:42
    我们还希望这只鸟能够与其他物体互动,所以让我们添加一个对撞机(Collider2D)。
  • 7:42 - 7:44
    2D圆形碰撞器 CircleCollider.
  • 7:44 - 7:50
    回到场景视图中,我们可以看到碰撞器有一个绿色的轮廓。对我来说有点偏离中心,
  • 7:50 - 7:55
    所以我将使用偏移(offset)来移动它。一个小游戏设计技巧,
  • 7:55 - 8:01
    如果我们使对撞机比图像小一点,它会让玩家容易通过管道,即使他们看起来摸到了边缘
  • 8:01 - 8:05
    它给了游戏一点宽容,让玩家觉得赚到了。
  • 8:05 - 8:11
    现在要添加的最后一项内容是:脚本(Script)。这本质上让我们自定义自己的组件。
  • 8:11 - 8:17
    但我们必须使用编程代码自己编写。组件列表选择: New Script
  • 8:17 - 8:22
    就叫它 Bird 脚本。加载后,双击脚本打开它
  • 8:22 - 8:27
    这将在我们之前安装的 Visual Studio 中打开该文件。
  • 8:27 - 8:31
    所以,欢迎来到编程!别慌,我保证不难,我们会慢慢来
  • 8:31 - 8:35
    我们用 C Sharp 写的,那是编程语言。
  • 8:35 - 8:41
    现在唯一需要担心的是这两个部分:启动和更新。
  • 8:41 - 8:47
    Start 用于在启用此脚本后将立即运行一次。
  • 8:47 - 8:53
    启用脚本时,Update 将持续运行,会不停的允许。
  • 8:53 - 8:57
    每一行代码,每一帧。一遍又一遍。
  • 8:58 - 9:03
    所以我们现在要用代码做的主要事情是-好吧,如果我们回去到 Unity
  • 9:03 - 9:08
    查看组件中的这些数字和文本字段,只要我们能在Unity中编辑它们
  • 9:08 - 9:13
    基本上,我们就可以编写代码来在游戏运行时更改这些属性。
  • 9:13 - 9:18
    举个愚蠢的例子,我们将在一秒钟内删除它。在开始阶段,
  • 9:18 - 9:26
    我们可以输入 gameObject 它指的是这里。然后输入一个 "."。你将看到出现一个列表,
  • 9:26 - 9:31
    许多项目引用了 Inspector 中的内容,如 IsStatic,标记、图层和名称
  • 9:31 - 9:39
    所以让我们选个 name。然后写一个等号,然后在引号中,给我们的鸟起个名字。
  • 9:39 - 9:45
    最后,我们必须始终使用分号(;)来标记一行代码的结束。
  • 9:45 - 9:50
    在我们回到Unity之前,我们必须保存一下脚本。
  • 9:50 - 9:54
    现在,当我们运行游戏..游戏对象的名称已更改,怎么样牛不牛。
  • 9:55 - 9:59
    好的,删除那个代码。那只是给傻子看的。
  • 9:59 - 10:03
    不过我们学会了使用代码与游戏交互了。我们可以通过写代码来操作某个东西。
  • 10:03 - 10:08
    比如游戏对象,然后名称,然后命令
  • 10:08 - 10:14
    将其更改为 Bob Birdington. 会经常写这种东西。
  • 10:15 - 10:20
    其实,我们真正想做的是..在刚体 2D 的组件中,在“信息”(Info)下,
  • 10:20 - 10:23
    我们会看到一个灰色的速度场。
  • 10:23 - 10:27
    想写一些代码来给鸟增加向上的速度,使它飞到空中。
  • 10:27 - 10:33
    问题是…。最初,脚本只能与游戏对象的顶部进行操作。
  • 10:33 - 10:37
    现在,这个脚本完全不知道其他组件。
  • 10:37 - 10:42
    所以我们需要先解决这个问题。我们需要在这个脚本上做一个特殊的插槽
  • 10:42 - 10:48
    一个 RigidBody2D-这样我们就可以与操作它并向它发送命令。这称为引用。
  • 10:48 - 10:52
    我们将在这里创建引用,在类名和 Start方法。
  • 10:52 - 10:58
    我们将编写 public RigidBody2D myRigidbody.
  • 11:01 - 11:06
    所以我们现在有一个插槽来存储 RigidBody2D.我们有一个可以参考的名字-
  • 11:06 - 11:12
    以确定我们需要的是这个特定的刚体 2D. 因为我们公开了它,我们从脚本外部访问此插槽。
  • 11:12 - 11:18
    所以如果我们回到 Unity,我们会看到脚本组件现在有一个用于 RigidBody2D 的字段。
  • 11:18 - 11:25
    我们可以把组件拖到那个槽里,放下。
  • 11:25 - 11:29
    我们已经在脚本和刚体之间建立了一条通信线路。
  • 11:29 - 11:36
    好的,回到 Visual Studio. 在 Update 中,我们可以输入 myRigidbody. 然后是点。
  • 11:36 - 11:40
    现在看看我们可以调用的所有东西。比如:角阻力,重力比例,质量
  • 11:40 - 11:46
    这些都是组件上的属性,我们需要的是速度(velocity)。
  • 11:46 - 11:51
    我们想把它设置为一个新的数字值,所以,就像前面的名字一样,我们将写一个等号。
  • 11:51 - 11:57
    现在我们在这里写的实际上是一个向量,它是两个数字,表示一个二维空间。
  • 11:57 - 12:02
    在这种情况下,它用来表示鸟飞行的方向。
  • 12:02 - 12:09
    我们想要鸟直接上升,所以是 (0, 1) 是可以的。我将使用 Vector2.up,
  • 12:09 - 12:14
    这是(0, 1)的内置简写。为了给它更多的能量,
  • 12:14 - 12:20
    我要将该矢量乘以一个数字。说,10,这应该可以把鸟送上西天。
  • 12:20 - 12:25
    现在,就像我之前说的,Update 中的任何代码都会每一帧反复运行,
  • 12:25 - 12:32
    所以如果我们保存脚本,并在 Unity 中点击播放..我们的鸟飞了。祈祷!
  • 12:32 - 12:36
    这样不行,最好只在玩家按空格键的时候。那么
  • 12:36 - 12:41
    是时候使用最基本的编程代码了:if 语句。
  • 12:41 - 12:43
    if 语句就像一个门。
  • 12:43 - 12:48
    你可以用大括号包围一些代码,代码的每一帧都将完全不执行
  • 12:48 - 12:52
    除非,游戏满足一些特定的条件
  • 12:52 - 12:57
    在门上-在这种情况下,门是打开的,代码被读取并执行。
  • 12:57 - 13:01
    所以我们想说“如果玩家按下空格键,然后加上向上的速度”。
  • 13:01 - 13:06
    为了做这个..我们可以写 if,然后在括号里写条件。
  • 13:06 - 13:12
    这次我们不是在讨论一个组件,而是在讨论 Unity 本身——特别是它的输入系统。
  • 13:12 - 13:20
    那么我们将编写输入。然后我们可以选择 GetKeyDown,并在括号中选择 KeyCode.space.
  • 13:20 - 13:25
    如果在该帧上按下了空格键。然后我们输入 “== true”。
  • 13:25 - 13:31
    关于等号的简要说明——我们用一个等号来使左边的东西等于右边一个值。
  • 13:31 - 13:35
    我们用两个如果我们只是在检查左边的东西和右边的一样
  • 13:35 - 13:39
    懂吗?
  • 13:39 - 13:44
    无论如何。所以这个代码说..如果空格键刚被按下,那么..然后我们会
  • 13:44 - 13:49
    将代码放在大括号里。
  • 13:50 - 13:54
    所以,现在在 Update 中-游戏的每一帧都会走到门口,然后被问到嘿,
  • 13:54 - 13:59
    空格键是否已按下?如果是,代码将运行,鸟将扇翅膀。如果没有,
  • 13:59 - 14:03
    它将跳过花括号中的代码,并在下一帧中重试。
  • 14:03 - 14:08
    所以-保存脚本,并返回到 Unity. 我们现在可以点击播放和 Tada:
  • 14:08 - 14:11
    当我们按空格键的时候,鸟就会飞起来。
  • 14:11 - 14:17
    我们现在已经创建了一个角色,并使用键盘控制它。这就是一个电子游戏。牛!
  • 14:17 - 14:23
    然而,它就像垃圾。这翅膀扇得不对,感觉不像原作。
  • 14:23 - 14:32
    所以我们可以改变这个数字。保存。回Unity,运行游戏。不太对。
  • 14:32 - 14:41
    停。更改一下。保存。不过好傻啊,我们搞点更聪明的办法吧
  • 14:37 - 14:42
    首先,我们要创建一个变量。让我们回到脚本的顶部和底部
  • 14:42 - 14:47
    我们参考刚体,让我们制作一个名为 flapStrength 的公共插槽。
  • 14:47 - 14:52
    一个浮点数(float)-是一个可以有小数位的数字。
  • 14:52 - 14:58
    然后回到我们的更新代码中,我们将 Vector2.up 乘以 flapStrength,而不是 10。
  • 14:58 - 15:02
    现在,回到 Unity 中,你将看到脚本组件有一个新字段:flapStrength
  • 15:02 - 15:07
    我们可以随时改变这一点,让游戏手感更有感觉。
  • 15:07 - 15:11
    我们甚至可以在游戏中更改它,但请注意,你更改的任何内容
  • 15:11 - 15:15
    当你按下“停止”时,正在运行的游戏不会保存。这意味着你可以玩
  • 15:15 - 15:19
    你可以尽情享受你的更改,而不用担心搞砸你的游戏。
  • 15:19 - 15:23
    所以,如果我们弄乱了flapStrength,还有刚体重力缩放
  • 15:23 - 15:27
    我们希望能得到一些感觉良好的东西。
  • 15:27 - 15:30
    来回变换数字:观众老爷,这就是游戏设计!
  • 15:30 - 15:31
    接下来复习一下。
  • 15:31 - 15:36
    在游戏运行时,我们可以使用代码来更改组件的属性。
  • 15:36 - 15:41
    默认情况下,脚本不能与游戏对象上的其他组件对话。
  • 15:41 - 15:45
    你必须通过存储对该特定组件的引用来建立通信线路。
  • 15:45 - 15:50
    我们在代码中创建引用,然后通过拖放在 Unity 中填充它。
  • 15:50 - 15:56
    当脚本出现时,Start 中的代码只运行一次。Update 中代码每一帧连续运行,
  • 15:56 - 16:02
    但是,我们可以使用 if 语句跳过一些代码,除非满足条件。
  • 16:02 - 16:05
    我们可以使用公共变量来改变某些Unity 的 Inspector 中的值
  • 16:05 - 16:08
    即使在游戏运行时。
  • 16:09 - 16:14
    好的,Flappy Bird 的秘密是,虽然它看起来像一只鸟
  • 16:14 - 16:18
    在一个充满管道的世界里飘动,但实际上是
  • 16:18 - 16:24
    鸟保持完全静止,管道在屏幕上移动。所以在第三步中我们
  • 16:24 - 16:29
    让管道在世界上生成,在屏幕上移动,然后出去屏幕后移除它们。
  • 16:29 - 16:32
    我们将从制作我们想要生成的对象开始。
  • 16:32 - 16:35
    这将是从左到右穿过屏幕的两根管道。
  • 16:35 - 16:40
    让我们创建另一个名为“管道”的游戏对象。现在把它准确地移动到鸟中间,
  • 16:40 - 16:45
    以获得正确的相对位置。然后我们将在这个中创建另一个对象,称为顶管。
  • 16:45 - 16:51
    这是第一个和父对象和子对象层级有关的游戏对象。
  • 16:51 - 16:55
    这边我们可以嵌套多个游戏对象,并通过移动父对象一次移动所有子对象
  • 16:56 - 17:00
    所以让我们还是重复像制作鸟的过程一样,为管道图像添加精灵渲染器。
  • 17:01 - 17:07
    并添加一个碰撞器-这次是一个 2D 的盒子碰撞器(BoxCollider)。我们不需要刚体,
  • 17:07 - 17:13
    因为它不会受到物理学的影响。然后我们可以把它移到鸟的上方,但保持 X 的位置为零。
  • 17:13 - 17:19
    最后,我们可以复制整个顶部管道对象。然后叫它底管。然后翻转一下
  • 17:19 - 17:24
    通过将 Y 刻度更改为-1,将其颠倒。然后把它移到鸟的下面。
  • 17:24 - 17:31
    如你所见,如果我们改变管道父游戏对象,两个管道都会以父对象作为轴点
  • 17:31 - 17:35
    移动,缩放,并与其一起旋转。
    204
    00:17:35,400 --> 00:17:38,940
    将脚本添加到此父对象,使其在屏幕上移动。
  • 17:41 - 17:46
    我们首先为 moveSpeed 创建一个变量。如果我们在这里给它一个数字,
  • 17:46 - 17:51
    它将填充此值作为 Unity 中的默认值。但我们以后可以随时改变它。
  • 17:51 - 17:56
    然后,我们将在更新中编写代码来移动对象。如果我们能
  • 17:56 - 18:03
    键入 transform.position.x,然后直接更改此数字,但其实不是,Boo,
  • 18:03 - 18:09
    你必须一次完成整个Vector的更改。哦,这次我们要用Vector3,而不是矢量 Vector2,
  • 18:09 - 18:15
    因为 position 有三个数字。尽管我们在制作 2D 游戏,但从根本上说
  • 18:15 - 18:20
    Unity 仍然是一个 3D 引擎,因此它通过 Z 值来跟踪对象的深度。
  • 18:21 - 18:26
    所以,我们要做的是。我们将transform.position, 然后等于。
  • 18:26 - 18:31
    我们想要添加到它的位置,所以再次编写
  • 18:31 - 18:37
    transform.position = transform.position + (Vector3.left * moveSpeed);
  • 18:39 - 18:44
    返回 Unity,按“播放”。卧槽,太快了。
  • 18:44 - 18:48
    现在,你可能认为你可以把这个 moveSpeed 变量改成
  • 18:48 - 18:53
    像 0.001 这样的小数字。这会起作用——但这实际上不是问题所在。
  • 18:53 - 18:59
    你可以看到,Update 中的代码只是尽可能频繁地运行。事实上,如果我们在游戏视图中查看属性,
  • 18:59 - 19:03
    我们将看到游戏以每秒超过 1000 帧的速度运行。嘿,
  • 19:03 - 19:08
    对不起,PlayStation 5,每秒 120 帧?呸,这和《Flappy Bird》没什么关系。
  • 19:08 - 19:12
    真正的问题是游戏可能在不同的计算机上以不同的速度运行,
  • 19:12 - 19:16
    我们不希望管道移动得更快或更慢,这取决于你的电脑。
  • 19:16 - 19:23
    真实游戏其实也犯过这个错误——在《黑暗之魂 2》中,武器耐久度随每帧耐久度下降
  • 19:23 - 19:31
    所以你的剑在每秒 60 帧时会比每秒 30 帧快两倍。那真是太棒了。
  • 19:31 - 19:36
    幸运的是,这是一个很容易解决的问题。我们只需乘以 Time.deltaTime.
  • 19:36 - 19:41
    这确保了无论帧速率如何,乘法都会计算出相同的值。
  • 19:41 - 19:45
    不过在velocity的代码上则不需要它,因为物理运行在它自己的小时钟上,
  • 19:45 - 19:49
    如果你想知道更多-关于这件事,或者任何事,
  • 19:49 - 19:54
    Unity 文档是一个好地方。你会找到更多和示例代码。
  • 19:54 - 19:59
    好的,现在有了这个解决方案,我们的管道可以在屏幕上平滑地移动。可爱的。
  • 19:59 - 20:05
    接下来,我们要创建一个将不断生成新管道的系统。首先,
  • 20:05 - 20:11
    从层次结构中获取父游戏对象并将其拖动到项目中。这将创建一个预制游戏对象(Prefab)。
  • 20:11 - 20:17
    或叫预制。这就像一个游戏对象的蓝图,我们通过这个蓝图
  • 20:17 - 20:22
    创建新的整个游戏对象的另外版本,会包括所有子对象、组件和属性。
  • 20:22 - 20:26
    在我们继续之前,我们现在可以删除层次结构中的原始内容。拜拜。
  • 20:26 - 20:29
    让我们创建一个名为“管道产生成器”的新游戏对象。
  • 20:31 - 20:36
    我们会把它放在摄像机的右边。我们会为它做一个脚本。
  • 20:36 - 20:42
    脚本将每隔几秒生成管道预置的新版本。因为管道已经
  • 20:42 - 20:47
    有向左移动的代码,管道将在生成后立即自动在屏幕上移动。
  • 20:47 - 20:51
    我们将编写一些代码来生成我们刚刚制作的预置。那么
  • 20:51 - 20:54
    我们将从引用预制件开始。
  • 20:54 - 20:59
    在这里,我们将输入公共游戏对象管道。
  • 20:59 - 21:04
    然后在 Unity 中,我们将使用相同的拖放方法来填充插槽,但这一次,
  • 21:04 - 21:08
    我们将从“项目”面板中拖动预置,而不是组件。
  • 21:08 - 21:12
    现在,Unity 有一个很好的内置生成对象的方法。
  • 21:12 - 21:18
    新游戏对象。我们将输入 Instantiate,然后打开括号。
  • 21:18 - 21:23
    在这里,需要填一些额外的细节。我们实际上可以通过翻阅这些找到不同的,怎么说呢,食谱吧?
  • 21:23 - 21:28
    我猜?这个看起来不错,它将在指定的位置和旋转创建一个对象。
  • 21:28 - 21:33
    因此,对于游戏对象,我们可以输入 pipe. 对于位置
  • 21:33 - 21:38
    我们可以只输入 transform.position 来获取对象的位置。
  • 21:38 - 21:42
    意思是说,会把管道生成在生成器所在的位置。
  • 21:42 - 21:47
    并且对于旋转,让我们只使用 transform.rotation 和生成器也相同。
  • 21:48 - 21:53
    让我们运行它,天啊,这不是我们想要的。生成效果很好,
  • 21:53 - 21:56
    但他们每一帧都在出现,我们希望他们出现。
  • 21:56 - 22:00
    在一个我们可以控制的好时间里。所以,回到 Visual Studio.
  • 22:00 - 22:05
    我们现在要做的是写一些代码来制作一个计时器。这将计入
  • 22:05 - 22:10
    指定的秒数,运行一些代码,然后再次开始计数。要做到这一点,
  • 22:10 - 22:15
    我们需要做几个变量。生成器应该指它应该有多少秒生产一个管道
  • 22:15 - 22:20
    然后计时器是计数的数字。我们可以做这个。
  • 22:20 - 22:23
    一个私人的,因为我们不会在编辑器或其他任何地方更改它。
  • 22:23 - 22:29
    在Update中,我们将执行另一个 if 语句。此时,如果计时器小于 spawnRate,
  • 22:29 - 22:35
    然后我们让计时器加一。因此,我们将采用当前的计时器,
  • 22:35 - 22:40
    并将 time.deltatime 添加到其中。这将创建一个计数每一帧的数字,
  • 22:40 - 22:43
    无论你的计算机的帧速率是多少,它的工作方式都是相同的。
  • 22:43 - 22:48
    实际上,我们可以通过将其更改为 += 来缩短它,但是,不要觉得你需要将代码设置为尽可能短
  • 22:48 - 22:53
    只是为了避免大佬们不屑的评论。
  • 22:53 - 22:58
    如果:"timer = timer + xxx" 更容易阅读和掌握,那么这绝对没问题。
  • 22:58 - 23:02
    你熟练了,可以随便使用。
  • 23:02 - 23:05
    现在,在我说 if 语句之前,它就像一扇门。
  • 23:05 - 23:10
    我们可以在它的旁边添加另一个门,否则。这意味着,
  • 23:10 - 23:15
    如果不满足条件,则跳过该代码,并在 else 中执行该代码。
  • 23:15 - 23:23
    因此,我们将在这里放入生成代码,并将计时器重置为零。所以现在,每一帧,
  • 23:23 - 23:28
    询问计时器是否小于生成率。如果是的话,那就把计时器算起来。如果不是
  • 23:28 - 23:33
    即计时器实际上已经达到或超过了生成速率,然后生成一个管道并再次启动计时器。
  • 23:33 - 23:39
    把这个放在 Unity 里-很好。我对此很满意。唯一的问题是。
  • 23:39 - 23:44
    我们必须等待第一个管道生成的时间很长。如果这个马上出来就好了,对吧?
  • 23:44 - 23:50
    现在,我们可以将代码复制并粘贴到 Start 中,这样它就会在 Start 中发生一次。
  • 23:50 - 23:55
    然后在更新中一遍又一遍地发生。但这是个坏主意。你通常应该试着
  • 23:55 - 24:01
    避免在多个位置使用相同甚至相似的代码。
  • 24:01 - 24:06
    如果我们想要改变生产的工作方式?我们必须各处寻找并修改它,不是很好。
  • 24:06 - 24:10
    相反,我们可以将代码放在一个新函数中,然后运行它
  • 24:10 - 24:15
    所以在这里,下面的Update,但在最后的花括号上面-我们将
  • 24:15 - 24:21
    创建一个名为 void SpawnPipe()的函数。然后将实例化代码剪切并粘贴到其中。
  • 24:21 - 24:28
    现在,我们只需在 Update 和 Start 中编写带有空括号的 SpawnPipe.这将运行
  • 24:28 - 24:32
    执行这些行时该函数中的所有代码。做完这件事,
  • 24:32 - 24:38
    它会让游戏一开始就有一个管道,并且每次计时器达到最大值时都会产生新的管道。牛了。
  • 24:39 - 24:45
    然而,这是一个相当无聊的游戏,对不对?管子总是从中间出来。我们想要他们
  • 24:45 - 24:49
    以随机的高度出现。请记住,当我们编写实例化代码时,
  • 24:49 - 24:53
    我们必须选择一个物体出现的位置。我们将更改该值。
  • 24:53 - 24:58
    现在,管道总是在与生产器相同的位置生产。我们想要 X 值
  • 24:58 - 25:04
    是一样的..但对于 Y,我们想要在生产器上方或下方的某个位置随机选择一个点。
  • 25:04 - 25:09
    因此,让我们为高度偏移创建一个公共变量,可能是 10。
  • 25:09 - 25:14
    然后我们将创建一个名为 lowestPoint 的浮点数。因为我们在函数,
  • 25:14 - 25:20
    而不是在脚本的顶部,这意味着它只能在函数中使用。但是,
  • 25:20 - 25:22
    这也意味着我们可以通过计算来设置它。
  • 25:22 - 25:30
    因此,我们将执行 = transform.Position.y - heightOffset. 然后我们再做一个。
  • 25:30 - 25:37
    一个是最高点,但这次是加上高度偏移。这样我们就得到了这两个数字。
  • 25:38 - 25:41
    然后,我们将替换实例化代码中的 transform.position.
  • 25:41 - 25:47
    我们要写一个新的Vector3,每当我们指定我们自己的数字时,我们必须用 Vector3
  • 25:47 - 25:54
    然后在括号中,我们将 x、y 和 Z 值指定为三个不同的浮点数。对于 X,
  • 25:54 - 25:59
    我们希望这与生成器相同,所以我们将执行 transform.position.x.
  • 25:59 - 26:05
    但是对于 y,我们可以做随机范围。在括号里,我们可以提供一个最小值和最大值。
  • 26:05 - 26:12
    从中挑选。这是最低点和最高点。然后用 0 表示 Z,并关闭括号。
  • 26:14 - 26:20
    回到Unity..好的!管道将在这两个数字之间的任何位置生成。
  • 26:20 - 26:25
    哦最后一件事。每次这些管道生产时,它们都会出现并向左移动..永远。
  • 26:25 - 26:30
    这不是很好的方式——他们在屏幕外什么也不做,
  • 26:30 - 26:35
    然而,它们仍然在内存中,每一帧都在运行代码。如果太多,它们就会
  • 26:35 - 26:40
    把你的电脑内存全吃掉,然后崩溃。所以让我们解决这个问题。
  • 26:40 - 26:45
    现在,我们可以制作一个计时器,并在几秒钟后删除管道。但是相反,
  • 26:45 - 26:51
    我们将检查管道的 X 位置,如果它超过了某个点,则将其删除。我们会借的
  • 26:51 - 26:58
    这只鸟找出了屏幕左边的 X 坐标。看起来大约是零下 45 度
  • 26:58 - 27:06
    在管道移动脚本中,我们将为死区添加一个浮动。-45. 然后是一个简单的 if 语句-if
  • 27:06 - 27:13
    如果 Transform.Position.X 小于 DeadZone,则销毁保存此脚本的游戏对象。
  • 27:16 - 27:19
    在 Unity 中运行它,然后,砰,他们死了。
  • 27:19 - 27:24
    让我们再做一件事,像个学生一样。就在销毁之前,
  • 27:24 - 27:33
    让我们编写 Debug.Log,并在括号中删除管道。然后,回到 Unity 中,
  • 27:33 - 27:39
    你将看到另一个面板我在 UI 演示过程中跳过了-它是 Project 旁边的一个选项卡,称为 Console.
  • 27:39 - 27:45
    然后当我们运行游戏..每次删除管道时,我们的消息都会发送到控制台。
  • 27:45 - 27:50
    这是一种非常有用的调试代码的方法,因为我们可以准确地找出代码的目的。
  • 27:52 - 27:53
    回顾时间!
  • 27:53 - 27:56
    游戏对象可以转换为预制件,
  • 27:56 - 27:59
    通过将它们从层次结构中拖放到项目中。
  • 27:59 - 28:04
    然后你可以把它们拖到场景中, 我在我的益智游戏中使用预制件来创建关卡。
  • 28:04 - 28:09
    比如说。或者你可以在游戏中创建一个生产器来实例化新的生产器。
  • 28:09 - 28:13
    计时器是一种使代码在特定时间间隔内发生的好方法,
  • 28:13 - 28:17
    但始终使用 time.deltatime 来保持不同计算机之间的一致性。
  • 28:17 - 28:22
    if 语句可以有一个 else 的门,以使代码在条件未满足。
  • 28:22 - 28:27
    你也可以有其他的 if,来制作更复杂的门。
  • 28:27 - 28:31
    如果不再需要游戏对象,你应该尝试删除它们,以释放内存。
  • 28:32 - 28:36
    好的,我们下一步是记录玩家的得分,
  • 28:36 - 28:39
    并在用户界面上将其显示给玩家。然后,
  • 28:39 - 28:43
    我们希望每次鸟穿过管道时,分数都能上升一分。
  • 28:43 - 28:47
    因此,请记住,游戏对象不一定是游戏中的物理对象
  • 28:47 - 28:53
    世界就像一个角色或一个敌人-它可以是一个完全看不见的管理者
  • 28:53 - 28:58
    这只是跟踪关键数据,如HP、时间或分数。然后,
  • 28:58 - 29:01
    我们可以使用用户界面让玩家看到这些信息。
  • 29:01 - 29:07
    所以让我们开始制作 UI。像其他东西一样,在层级面板,它是一个游戏对象。
  • 29:07 - 29:12
    这一次,向下到 UI 并选择文本,它可能在Legacy
  • 29:12 - 29:17
    我们需要将场景视图放大到非常远的地方,才能真正看到 UI.
  • 29:17 - 29:22
    为了确保 UI 在每个设备上看起来都一样,我们将选择这个新的画布游戏对象
  • 29:22 - 29:28
    将画布缩放器组件的 UI 比例设置为随屏幕大小缩放,并选择合理的
  • 29:28 - 29:34
    参考分辨率-我将再次使用 1080p.然后,我们可以移动文本。你会注意到
  • 29:34 - 29:40
    该 UI 具有 Rect Transform,而不是正常 Transform。最重要的是要注意
  • 29:40 - 29:45
    你真的先不要使用 scale改变大小,而是用宽度和高度。
  • 29:47 - 29:49
    然后,我将增加字体大小并设置默认值。
  • 29:49 - 29:53
    文本设置 0. 然后检查它在游戏视图上看起来都很好。
  • 29:53 - 29:57
    好的,现在我们要做一个脚本来存储玩家的分数,
  • 29:57 - 30:00
    并将 UI 上的数字更改为该分数。
  • 30:00 - 30:03
    我们将制作一个名为逻辑管理器(Logic Manager)的游戏对象。
  • 30:04 - 30:09
    我们会给它一个脚本。此脚本将跟踪高级信息
  • 30:09 - 30:14
    比如玩家得分。它将具有我们可以运行的各种基本功能。
  • 30:14 - 30:18
    因此,我们将删除 “Start”和“Update”,我们在此脚本中不需要它们。我们可以随时添加
  • 30:18 - 30:23
    如果我们后面还要,可以加回来。我们想为玩家的分数存储一个数字。这一次,
  • 30:23 - 30:28
    我们不想要浮点数,因为我们只想要整数。所以让我们做一个整数,
  • 30:28 - 30:30
    这是个整数。没有小数位。
  • 30:30 - 30:35
    因为我们想要更新我们刚刚创建的 UI 文本,所以我们将一如既往地
  • 30:35 - 30:41
    必须做一个引用。但是,好像没找到合适的。
  • 30:41 - 30:46
    啊,好吧。默认情况下,脚本只加载Unity所需的基础内容。
  • 30:46 - 30:52
    但如果我们在顶部输入 UnityEngine.UI;,我们现在可以
  • 30:52 - 30:59
    访问更多的功能-在这种情况下,是用户界面的东西。现在我们可以参考文本。
  • 30:59 - 31:05
    我们需要将文本组件拖回 Unity 中的这个字段。因为我们正在引用一个组件
  • 31:05 - 31:10
    在另一个游戏对象(UI 上的文本)上,最好的方法就是
  • 31:10 - 31:16
    拖动整个游戏对象进入我们的插槽。这将自动为我们找到文本组件。方便。
  • 31:16 - 31:20
    所以现在我们要做一个函数。我们称之为 AddScore.
  • 31:20 - 31:25
    还有因为我们将从其他脚本运行此函数,并将其设置为 public void.
  • 31:26 - 31:31
    这个函数需要做两件事。在玩家的分数上加一。很容易,
  • 31:31 - 31:39
    我们现在知道该怎么做了。并将 UI 上的文本更改为此数字。哦,文本框是
  • 31:39 - 31:46
    寻找一个字符串-字符序列-我们的分数是一个整数。他们看起来一模一样
  • 31:46 - 31:52
    对我们人类来说,但程序是挑剔的。请注意,通过将.ToString()添加到游戏分数中,很容易修复。
  • 31:53 - 31:57
    为了确保这一点,让我们自己来运行这个函数。
  • 31:57 - 32:03
    从Unity本身。我们需要做的就是在函数上面写上 ContextMenu 和一个名称。
  • 32:05 - 32:10
    现在,在 Unity 中,当游戏运行时,点击这个脚本上的小点并选择函数。
  • 32:11 - 32:14
    好看的!这类东西在测试中非常方便。
  • 32:15 - 32:19
    好的,现在我们知道函数运行了,我们特别想运行它。
  • 32:19 - 32:23
    当鸟在管道之间穿行时。而做到这一点的方法是碰撞。
  • 32:23 - 32:28
    现在,如果两个物体有碰撞器,它们会互相撞击-事实上,在我们的游戏中,
  • 32:28 - 32:33
    这只鸟已经撞进了管道,因为我们在两个管道上都增加了对撞机。然而-你
  • 32:33 - 32:38
    也可以有不可见的碰撞器,称为触发器(Trigger)。它们不会造成真正的碰撞,
  • 32:38 - 32:42
    但是它们确实让你知道两个对象已经接触-并且你可以在此时运行代码。
  • 32:42 - 32:45
    所以我们要在管道之间放一个触发器,
  • 32:45 - 32:51
    所以我们知道这只鸟穿过了它们。然后在那个时候,我们将运行 addScore.
  • 32:51 - 32:56
    让我们打开管道的预置。我们将制作另一个名为“middle”的游戏对象
  • 32:56 - 33:01
    它需要一个盒子对撞机。让我们把它做成这种形状。这次我们要
  • 33:01 - 33:06
    在 Is Trigger 框中打勾。最后,让我们为这个新的中间游戏对象添加一个脚本。
  • 33:06 - 33:14
    在 Update 下面,输入 OnTrig,按Tab,自动将帮助我们输入 OnTriggerEnter2D.
  • 33:14 - 33:19
    此函数意思是,任何内容进入碰撞器的第一次时都将运行
  • 33:19 - 33:26
    还有 OnTriggerExit 和 OnTriggerStay,供将来参考。
  • 33:26 - 33:30
    我们要运行之前编写的 addScore 函数..除了。啊哈。再一次,
  • 33:30 - 33:34
    这个脚本不知道游戏中的任何其他脚本,直到我们引用它。
  • 33:34 - 33:41
    所以我们可以编写公共逻辑脚本逻辑。但回到 Unity,你很快就会意识到
  • 33:41 - 33:46
    你不能把脚本拖到这个槽中。你不能把它从项目中拖出来
  • 33:46 - 33:51
    我们只能与游戏对象上的脚本实例来操作。
  • 33:51 - 33:57
    但我们也无法从场景拖动到预置中。这是因为场景中还不存在管道,
  • 33:57 - 34:01
    只有当游戏运行时,生产器开始制作管道时,它才会存在。
  • 34:01 - 34:06
    因此,我们需要使用代码来填充此引用。
  • 34:06 - 34:08
    这需要在管道首次生成时进行。
  • 34:08 - 34:13
    为此,我们需要帮助代码找到逻辑脚本。
  • 34:13 - 34:17
    要做到这一点,以游戏逻辑对象为例,查看检查器的顶部:
  • 34:17 - 34:24
    你会看到标签。从下拉列表中选择“添加标记”。创建一个新的标签,
  • 34:24 - 34:30
    并确保你回到游戏对象并实际设置这个新标签。你不会忘记的
  • 34:30 - 34:35
    在你的Unity职业生涯中,这样做大约 8000 次,所以期待吧。
  • 34:35 - 34:37
    现在,回到 PipeMiddleScript 中,
  • 34:37 - 34:47
    在 Start 下,我们可以写 logic = Gameobject.FindGameObjectWithTag("logic")。
  • 34:47 - 34:51
    这将在层次结构中寻找第一个带有logic标签的游戏对象,
  • 34:51 - 34:54
    在我们的例子中,场景中永远只有一个,
  • 34:54 - 34:58
    所以我们知道它总会找到合适的——但一定要注意这一点。
  • 34:58 - 35:02
    然后我们可以添加.GetComponent();
  • 35:03 - 35:09
    所以,一旦一个新的管道产生,它就会通过层次结构来寻找一个有logic标签的游戏对象。
  • 35:09 - 35:14
    然后,它将查找该对象的组件以找到脚本LogicScript。
  • 35:14 - 35:19
    如果它找到一个,它会把它放在我们的参考槽中。
  • 35:19 - 35:23
    它完成了与拖放组件到插槽完全相同的操作。
  • 35:23 - 35:28
    当然,区别是通过代码在运行时做到的。
  • 35:29 - 35:34
    所以现在,管道的中间脚本可以找到逻辑脚本并与之操作。
  • 35:35 - 35:41
    如果我们编写 logic.addScore,它将运行该代码。回到Unity,
  • 35:41 - 35:47
    点击播放,如果我们一切都做得很好,当我们通过管道之间时,分数将上升一分。
  • 35:47 - 35:53
    哦,不过为了后面更好的做其他事情,让我们确保通过管道的确实是这只鸟。
  • 35:53 - 35:58
    我们将通过把鸟放在一个层(Layer)上,并设置碰撞是否有效。
  • 35:58 - 36:04
    转到鸟的游戏对象,这一次,而不是标签,我们将改变鸟的层
  • 36:04 - 36:11
    添加一个新的,记得回来设置一下,并记下数字。
  • 36:11 - 36:15
    现在,在管道的中间脚本上,我们可以在 addScore 周围添加一个 if 语句,
  • 36:15 - 36:20
    并检查刚刚发生的碰撞是否与属于 Bird 层上的游戏对象。
  • 36:23 - 36:27
    当我们谈到这个话题的时候,还有一点需要做的。回到Logic Script。
  • 36:27 - 36:33
    让我们以 addScore 函数为例,在这些空括号中,
  • 36:33 - 36:39
    我们将写下 int scoreToAdd. 然后,我们将添加 soreToAdd,而不是添加一个 1。
  • 36:39 - 36:45
    然后,在管道中间脚本中,我们可以在 addScore 后面的括号中写入 1.
  • 36:45 - 36:50
    对的,现在,这和我们以前做的事情完全一样。但是,你肯定能猜到,
  • 36:50 - 36:55
    稍后,你可以在游戏中添加一些其他目标,例如,在你的得分上添加 5。
  • 36:55 - 36:59
    这使我们可以使函数更通用,因为它可以使用
  • 36:59 - 37:03
    以不同的方式,从不同的地方。我认为成为一名优秀程序员的一部分,
  • 37:03 - 37:07
    是让东西变得不那么死板,并为未来的想法保持开放。
  • 37:07 - 37:13
    这使得对设计进行迭代变得更加容易和快速。
  • 37:13 - 37:14
    对的!回顾!
  • 37:14 - 37:18
    UI 只是另一个游戏对象,但如果我们想在这些组件中引用
  • 37:18 - 37:23
    我们需要将 UnityEngine.UI 添加到脚本的顶部。
  • 37:23 - 37:26
    游戏对象可以是完全看不见的东西,
  • 37:26 - 37:30
    只是在那里管理规则、逻辑、分数等等。
  • 37:30 - 37:34
    如果我们想在一个游戏对象不在场景中的时候引用一个组件,
  • 37:34 - 37:37
    我们需要在运行时找到该组件。
  • 37:37 - 37:42
    一种方法是使用Tag、FindGameObject 和 GetComponent.
  • 37:42 - 37:47
    只要有引用,就可以从另一个脚本运行公共函数。
  • 37:47 - 37:51
    对那个脚本。我们甚至可以在该函数运行时传入变量。
  • 37:51 - 37:57
    当两个物体接触时,碰撞和触发可以用来使事情发生。
  • 37:57 - 37:59
    说到碰撞,让我们进入下一步……
  • 38:01 - 38:07
    最后一步是添加失败状态。当鸟撞到管道时,游戏就结束了。
  • 38:07 - 38:11
    我们将通过在屏幕上制作一个游戏结束界面来做到这一点,并让它在鸟碰到管道坠毁时出现。
  • 38:11 - 38:16
    游戏结束界面将有一个按钮,我们可以用它来重置游戏。
  • 38:17 - 38:21
    首先,让我们在屏幕上制作游戏结束界面。在画布游戏对象上,
  • 38:21 - 38:28
    添加一个新的空的游戏结束界面。然后,在该父项中,添加“游戏结束”文本。
  • 38:31 - 38:37
    还有一个按钮-也在 Legacy 下。调整它的大小。
  • 38:37 - 38:42
    和改变按钮上的文本,该文本可以作为按钮本身的子项找到。
  • 38:43 - 38:48
    所以回到按钮游戏对象上,在按钮组件上,你会看到
  • 38:48 - 38:54
    点击时显示的这一点。这是一个事件,它允许我们调用
  • 38:54 - 38:59
    游戏对象上的公共函数。所以让我们做一个重启关卡的函数。
  • 39:00 - 39:02
    我们可以将这段代码放在逻辑脚本中,
  • 39:02 - 39:07
    在我们的 addScore 函数下面。如果你愿意,你可以做一个单独的脚本,
  • 39:07 - 39:12
    但我觉得这很好。让我们创建另一个名为 RestartGame 的公共函数,
  • 39:12 - 39:18
    在这里,我们将编写代码来重新启动场景。就像以前的用户界面一样管理场景
  • 39:18 - 39:23
    然后,我们需要在顶部添加一行-这一次,使用 UnityEngine.SceneManagment.
  • 39:24 - 39:30
    现在,在我们的函数中,我们将调用 SceneManager.LoadScene.
  • 39:30 - 39:35
    这需要一个场景的名称。其实就是场景的文件名。但是因为我们想要当前的场景,我们
  • 39:35 - 39:43
    可以简单地输入 SceneManager.getActiveScene,方括号,.name。
  • 39:45 - 39:48
    现在回到 Unity 中,向此按钮添加一个事件。
  • 39:49 - 39:53
    然后拖入逻辑游戏对象。并找到 RestartGame 函数。
  • 39:57 - 40:03
    简单测试一下..。好的,每次我们按下按钮,游戏就重新开始。
  • 40:03 - 40:08
    现在很明显,我们不想让它一直出现在屏幕上——只是在我们失败的时候。那么,
  • 40:08 - 40:12
    我们可以将整个游戏置于屏幕游戏对象之上,并使用此复选标记将其禁用。
  • 40:13 - 40:16
    那我们就让它在鸟撞进管道的时候出现。
  • 40:16 - 40:23
    我们先写函数。同样,在逻辑脚本中,让我们为 GameOver 创建一个公共函数。
  • 40:23 - 40:28
    我们需要对屏幕上的游戏对象进行引用。
  • 40:28 - 40:30
    并用Unity来填充它。
  • 40:31 - 40:39
    然后我们可以简单地在这个函数中输入 gameoverscreen.setActive true.
  • 40:39 - 40:42
    所以我们想让这个函数在鸟撞进管道时触发。
  • 40:42 - 40:48
    回到 Bird 脚本,让我们重用之前的代码来访问逻辑脚本。
  • 40:48 - 40:53
    是的,我们可以在 Unity 中拖放引用,但是,
  • 40:53 - 40:58
    我们现在已经编写了这段代码。然后我们将对触发器代码执行类似的操作,但这次
  • 40:58 - 41:03
    我们将使用 OnCollisionEnter2D,因为管道是实体对象,而不是设置为触发器。
  • 41:03 - 41:10
    当冲突发生时,使用 Logic.GameOver 触发游戏结束脚本。
  • 41:10 - 41:16
    回到Unity..这是可行的,但我们仍然可以在屏幕上玩游戏。不是很理想。
  • 41:16 - 41:21
    我已经讨论了几个关键的变量类型。浮子
  • 41:21 - 41:28
    整数是数字。字符串通常用于文本。另一个重要的是布尔,
  • 41:28 - 41:34
    布尔值的缩写。这是一个非常简单的类型,要么为真,要么为假。在上方,
  • 41:34 - 41:38
    或者关掉。是,或者不是。这是一种简单地检查或更改某物状态的好方法。
  • 41:39 - 41:44
    所以让我们有一个名为 birdIsLive 的布尔,并确保它开始为真。
  • 41:44 - 41:49
    然后,当碰撞发生时,我们将 birdIsLive 设置为 false.
  • 41:49 - 41:54
    最后,我们将在第一个 if 语句中添加一个额外的条件。
  • 41:54 - 42:01
    比如说,如果空格键刚刚被按下……由两个“”符号组成。而 birdIsLive 是等于真。
  • 42:01 - 42:06
    实际上,我们不需要加上这个 == true 的东西。是可以的。
  • 42:06 - 42:11
    没有它也一样。但是,再一次,这取决于你-也许写出完整的代码更容易阅读。
  • 42:11 - 42:17
    无论如何,现在,如果鸟死了,它就不会拍打翅膀,这对我来说似乎很合乎逻辑。
  • 42:17 - 42:24
    最后要做的是构建游戏。这真的很容易。选择文件、生成设置和生成。选择一个文件夹
  • 42:24 - 42:32
    你的硬盘。让Unity发挥作用。然后你可以打开这个文件来玩你的游戏!令人惊讶的。
  • 42:32 - 42:35
    在很短的时间内,我们制作了一个非常实用的游戏。
  • 42:35 - 42:40
    更重要的是,我们学到了很多关于Unity的基本知识。
  • 42:40 - 42:44
    我们创造了一个角色,它会根据我们的输入而移动。
  • 42:44 - 42:49
    我们有在计时器上生成新对象。我们已经创建了一个显示分数的 UI,
  • 42:49 - 42:54
    并在条件满足时使分数打勾。我们有能力结束一场比赛,
  • 42:54 - 42:56
    然后重新开始。
  • 42:56 - 43:00
    现在,我应该注意到,有不同的,也许更好的方法来做几乎所有的事情。
  • 43:00 - 43:05
    在本教程中。例如,我使用了 Unity 的传统方法来检查输入
  • 43:05 - 43:10
    Unity他们后来开发了一个非常非常好的输入系统。但要复杂得多
  • 43:10 - 43:16
    使用-所以这个简单的方法现在很好,你可以稍后再看看新的输入系统。
  • 43:16 - 43:21
    当你感觉更自信的时候。对我来说就是这样。还有 TextMeshPro,
  • 43:21 - 43:28
    已经取代了旧的Legacy用户界面系统-所以你会想要升级,在某些时候。
  • 43:28 - 43:32
    无论如何,这些都是对制作各种游戏有用的课程。
  • 43:32 - 43:37
    但是..游戏还没有完全结束。还有一些事情要解决。尽管,
  • 43:37 - 43:41
    我不想告诉你怎么做每件事。所以我会给你一些建议完成游戏,
  • 43:41 - 43:44
    我想让你自己试着搞定这些。
  • 43:44 - 43:48
    首先,如果小鸟从屏幕上消失,我们也需要让游戏结束。
  • 43:48 - 43:52
    这应该不会太难。还有一个错误,分数会一直上升,
  • 43:52 - 43:55
    即使在比赛结束后。也试着解决这个问题。
  • 43:55 - 44:00
    我们也想要声音效果。我想让你在逻辑管理器中添加一个音频源组件。
  • 44:00 - 44:06
    用音效文件填充它。在脚本上引用它。当分数上升时让它播放。
  • 44:06 - 44:11
    然后,我想让你玩一下粒子系统,让云出现在游戏中。
  • 44:11 - 44:16
    接下来,打开动画窗口,为小鸟添加一些拍动的翅膀。
  • 44:16 - 44:19
    然后我想让你添加另一个场景来制作一个标题菜单界面,
  • 44:19 - 44:23
    所以游戏不会立即开始行动。这里有一个提示:
  • 44:23 - 44:26
    你需要将此新场景添加到“构建设置”(Build Settings)窗口。
  • 44:26 - 44:31
    最后,如果你想要一个真正的挑战-使用 PlayerPrefs
  • 44:31 - 44:35
    将玩家的高分保存到硬盘上,并在用户界面上绘制。
  • 44:35 - 44:41
    对于其中的每一个,你可能会想要谷歌相关的术语,阅读 Unity 文档,
  • 44:41 - 44:45
    观看一些快速教程视频,或在下面的评论中寻求帮助。
  • 44:45 - 44:49
    接下来,你可以扩展一下《Flappy Bird》。发挥创意
  • 44:49 - 44:53
    并添加原始 iPhone 游戏中没有的想法或设计。
  • 44:53 - 44:58
    举个例子,我给了它发射导弹的能力,
  • 44:58 - 45:03
    然后我在管道上添加了目标。你现在必须用导弹击中目标才能打开。
  • 45:03 - 45:08
    一个你可以穿过的缝隙。它非常酷,为简单的游戏增加了更多的深度。
  • 45:08 - 45:12
    事实上,我很想看看你如何扩展原来的游戏。如果
  • 45:12 - 45:15
    你做一些有趣的东西,录一些片段,放到 YouTube 上,
  • 45:15 - 45:19
    并在评论中放置一个链接。将来我可能会介绍其中的一些。
  • 45:19 - 45:21
    最后,我建议你
  • 45:21 - 45:26
    做另一个简单的游戏,并尝试在 Unity 中重新制作它,就像我们现在所做的那样。
  • 45:26 - 45:31
    这是一个伟大的技术,因为你不必担心艺术或设计。
  • 45:31 - 45:35
    只是代码。你将面临的解决问题的难题就是一个很好的例子。
  • 45:35 - 45:39
    真正的游戏开发会是什么样子。
  • 45:39 - 45:46
    这方面的好候选人包括乒乓,太空入侵者,突破,弹出锁,愤怒的小鸟,
  • 45:46 - 45:52
    各种各样的 WarioWare 迷你游戏,如果你的互联网坏了,还可以在 Chrome 上玩恐龙游戏。
  • 45:52 - 45:55
    所以,在这个视频中,我想教你
  • 45:55 - 45:59
    Unity背后的基本概念-但是,剩下的就看你的了。
  • 45:59 - 46:04
    幸运的是,我认为这种亲自动手,自我指导,从错误中学习的风格
  • 46:04 - 46:10
    学习是最有趣、最有效的方法,可以让你坚持下去。但我们会看到的!
  • 46:10 - 46:14
    在下面的评论中让我知道你的进展。如果你
  • 46:14 - 46:17
    想看我的游戏开发故事吗-它仍在进行中,
  • 46:17 - 46:22
    承诺-然后点击这里,发展的第一集。
  • 46:22 - 46:25
    非常感谢我的赞助人——他们是让你不回吃土的爹地。
  • 46:25 - 46:31
    像这样的长视频中的广告。你可以在 patreon.com 上帮助支持 GMTK.
Title:
The Unity Tutorial For Complete Beginners
Description:

more » « less
Video Language:
English
Duration:
46:39

Chinese, Simplified subtitles

Revisions