WEBVTT 00:00:00.000 --> 00:00:04.295 Unity 4.3 我们发布了第一阶段的2D工具 00:00:04.295 --> 00:00:08.295 为此,我们用这个工具做了一个2D范例 00:00:08.295 --> 00:00:11.527 这个2D范例叫做"铁桥塔防" 00:00:11.527 --> 00:00:15.556 描述伦敦铁桥被外星人入侵的故事 00:00:15.556 --> 00:00:23.472 范例完全用2D图片和物理来呈现 让你了解这些元素如何在Unity里组合 00:00:23.472 --> 00:00:31.639 影片会说明范例里的背景、前景、角色、特效 镜头追迹、动作和脚本程序是如何制作的 00:00:31.639 --> 00:00:36.139 开始之前,先来聊聊基本的Unity 2D工作 00:00:36.860 --> 00:00:43.040 首先,当要制作2D项目,你应该先设定工作环境为2D 00:00:43.040 --> 00:00:47.040 可以在建立新项目时在下拉选单设定 00:00:47.040 --> 00:00:53.172 或是在开发中到Edit - Project Settings - Editor调整 00:00:53.172 --> 00:00:59.630 这代表预设情况下,输入的材质会 被视为2D图片,场景视图也会预设为2D 00:00:59.630 --> 00:01:04.420 这个新的2D模式会采用完全的 正视图视角来呈现你的2D游戏 00:01:04.420 --> 00:01:10.197 同时也会把右上角的3D小图示都隐藏 让工作空间更大 00:01:10.197 --> 00:01:17.040 除此之外,Unity 2D的工作流程 是和现有的3D流程整合在一起的 00:01:17.040 --> 00:01:22.929 如果你已经会操作原本的Unity 那Unity 2D会很好上手 00:01:22.929 --> 00:01:27.219 值得一提的是,你也可以混搭2D和3D共享 00:01:27.219 --> 00:01:32.870 所以如果你想要有3D元素在你的2D游戏里 或2D元素在3D游戏里都没有问题 00:01:33.366 --> 00:01:38.312 现在来看看范例如何建立一个关卡 00:01:38.812 --> 00:01:44.812 我们一开始勾勒关卡设计雏形 然后到Photoshop里面去把每个图层做出来 00:01:45.312 --> 00:01:51.312 然后输出这些图层 成为新的Sprite类型导入Unity 00:01:58.373 --> 00:02:06.515 为了呈现出背景的视差,我们做了一些 背景元素在Sorting Layer里 00:02:06.515 --> 00:02:09.658 这是一个2D工具的新功能 00:02:10.158 --> 00:02:17.379 当所有背景指定到这一层后 我们可以在图片着色器的图层排序它们 00:02:17.379 --> 00:02:21.379 调好位置之后也可以把图层锁定不能编辑 00:02:21.379 --> 00:02:27.751 这样的话我们编辑前景元素的时候 就不用担心会不小心动到背景元素 00:02:27.751 --> 00:02:31.751 可以从接口右上方的图层选单来设定 00:02:32.817 --> 00:02:39.531 由于背景只是装饰用的,所以 并不需要在图片上放任何组件 00:02:39.531 --> 00:02:41.531 将它们放到一个空的对象里 00:02:41.531 --> 00:02:46.201 并放入一个叫做叫做 BackgroundParallax的脚本来处里视差 00:02:46.201 --> 00:02:50.643 更多的细节可以详查这个已经批注的脚本 00:02:54.914 --> 00:02:59.400 接下来制作角色活动的前景空间 00:02:59.790 --> 00:03:03.466 我们设计了伦敦铁桥和降落在中间的飞碟 00:03:03.466 --> 00:03:09.216 主角处于一个敌人从天而降并到处乱窜的环境 00:03:09.216 --> 00:03:13.632 因此,每一个前景元素都需要 碰撞体(Collider)来让主角在上面行走 00:03:13.632 --> 00:03:21.239 大多数环境用方体碰撞就可以 除了外型比较复杂的飞碟 00:03:22.505 --> 00:03:28.724 Unity提供多边形碰撞体(Polygon Collider) 可以根据图片外型自动产生多边形碰撞体 00:03:28.724 --> 00:03:32.053 甚至可以调整碰撞体的外型 00:03:32.053 --> 00:03:38.164 你可以新增、移动或删除节点 调整到更适合行走的外型 00:03:38.664 --> 00:03:45.599 为了排序前景元素我们建立了前景层 设定显示在背景之前 00:03:48.875 --> 00:03:50.875 接下来看看主角 00:03:53.709 --> 00:04:03.598 我们的主角也是在Photoshop里面设计的 一个四肢独立类似卡通主角雷曼的角色 00:04:03.598 --> 00:04:05.598 另外一个2D工具的新功能 00:04:05.598 --> 00:04:09.643 是一个以图表化的动画工具 可以在Photoshop里绘制每一节点的图 00:04:09.643 --> 00:04:14.365 后面我们会介绍如何用这方法 制造我们的天鹅 00:04:15.072 --> 00:04:20.196 因为身体部位分开比较好控制动画 因此我们希望独立每个身体部位 00:04:20.196 --> 00:04:27.959 所以我们将身体部位独立切开 好让Unity在输入时容易拆离它们 00:04:28.763 --> 00:04:33.096 这代表我们可以为图片单独制作动作 00:04:33.096 --> 00:04:40.921 把这些部位放入建好的角色层 然后改变Z轴深度来改变前后顺序 00:04:48.811 --> 00:04:56.591 把这些图片都放入一个有控制脚本 碰撞体、物理设定等等的对象 00:04:56.591 --> 00:05:07.095 一旦做到这里,就可以到动画窗口给予图片动作 建立待机、跑、跳、射击和死亡的动画 00:05:07.095 --> 00:05:11.795 使用动画窗口里新的分镜表功能 就可以简单制作动作 00:05:13.414 --> 00:05:19.403 我们在父对象建立一个动画组件 然后针对每一个子对象建立影格 00:05:19.403 --> 00:05:25.403 移动指标到想要的影格后调整角色部位 就会自动把变量录到影格上 00:05:27.313 --> 00:05:35.064 可随时切换分镜表和动画曲线 使得它更容易调整设计 00:05:36.730 --> 00:05:41.370 这些动作建立好之后我们可以 帮我们的角色设计控制状态 00:05:41.370 --> 00:05:45.277 让我们用程序呼叫角色执行各种动作 00:05:45.277 --> 00:05:52.123 因为不是驱动3D骨架,所以取消打勾Root Motion 00:05:52.123 --> 00:05:57.287 也可以打勾Animate Physics如果 动画要和物理行为相互作用 00:05:57.287 --> 00:06:04.564 为了在场景走动,主角脚上有圆形碰撞体 和一个包覆整个身体的方形碰撞体 00:06:04.564 --> 00:06:09.454 这样他可以平顺地行走和跳下场景 跳起来的时候头部也可以判定撞到 00:06:09.802 --> 00:06:16.038 为了控制角色动作,我们写了 一个脚本透过2D物理引擎来移动 00:06:16.038 --> 00:06:21.427 这代表在游戏里面可以指定主角和敌人 让游戏动态更丰富的物理行为 00:06:21.427 --> 00:06:25.814 我们用PlayerControl脚本来判断角色的输入 00:06:25.814 --> 00:06:32.000 我们在此指定物理移动速度 同时也把输入的值送到动画控制器 00:06:32.000 --> 00:06:40.475 判定播放哪些动画以及 顺畅的播放分镜表上图片的转变 00:06:40.475 --> 00:06:44.475 使用动画控制建立图片动态最大的好处是 00:06:44.475 --> 00:06:51.278 可以调整动画速度用来搭配物理速度 不需要额外再作任何判定 00:07:23.129 --> 00:07:26.358 FixedUpdate函式会检查每一步物理运算 00:07:26.358 --> 00:07:32.994 在这里我们第一件要做的事情是 把输入的水平值传给动画的速度参数 00:07:33.950 --> 00:07:41.718 在我们的状态设定里 待机状态到跑动需要速度参数大于0.1 00:07:41.718 --> 00:07:46.025 当值成立时,动画就会从待机切到跑步 00:07:51.857 --> 00:07:58.822 要让角色移动,让它有Rigidbody2D组件 就可以为它加力道移动 00:07:59.626 --> 00:08:07.710 同时我们也根据输入的水平值是 大于0或小于0来处理角色面朝的方向 00:08:07.710 --> 00:08:14.573 这是因为在Unity里,按住左键会传回-1 而按住右键会传回+1 00:08:15.073 --> 00:08:24.566 根据输入值呼叫一个简单的翻转函数 来翻转角色的X轴缩放,让角色面向反方向 00:08:26.848 --> 00:08:31.000 为了判定角色是否着地 我们新增了一个Ground图层 00:08:31.000 --> 00:08:34.982 并指定给全部可行走的前景物件 00:08:43.397 --> 00:08:50.234 然后使用2D里面的Linecast函数 检查Ground图层是否和角色的脚接触 00:08:50.234 --> 00:08:56.777 为了让制作更容易,我们建立了 一个空白的对象当作检查地面的标准点 00:08:56.777 --> 00:09:03.083 在该对象上增加一个小图示 我们就可以控制角色到地面的距离 00:09:03.083 --> 00:09:07.958 就游戏角度来看 角色在地面时只能做跳的动作 00:09:08.456 --> 00:09:12.648 更多关于角色控制的信息 可以查看范例脚本里面的说明 00:09:12.648 --> 00:09:15.879 影片稍后也会讨论角色的武器 00:09:15.879 --> 00:09:19.879 接下来看看相机如何追踪角色 00:09:21.291 --> 00:09:27.824 跟3D游戏一样,在2D游戏里 镜头运镜也左右着游戏体验 00:09:27.824 --> 00:09:33.625 要呈现经典的2D游戏运镜 我们参考了2D游戏经典大作 00:09:33.625 --> 00:09:38.651 任天堂或超任的超级玛莉欧的镜头运作 00:09:38.651 --> 00:09:45.119 在超级玛莉欧世界里镜头会水平移动 除了封闭的空间或关卡边缘 00:09:45.119 --> 00:09:49.342 在这两类区域里角色小幅移动 镜头不会追踪 00:09:49.342 --> 00:09:54.047 一旦角色移出区域 镜头又会开始追踪角色 00:09:54.047 --> 00:09:58.205 超级玛莉欧的相机 用特定高度来进行垂直判定 00:09:58.205 --> 00:10:06.848 但我们的游戏没有往上的长度 比较像动作平台,所以不需要这类设定 00:10:07.210 --> 00:10:12.787 因此我们的相机在垂直判定 采用了和水平一样的方法 00:10:18.779 --> 00:10:25.138 请看看主相机里的CameraFollow脚本 了解镜头追踪更完整的写法和批注 00:10:26.135 --> 00:10:32.732 游戏中有许多特效 但最重要的是主角杀死外星人的能力 00:10:32.732 --> 00:10:36.338 主角会发射一个具有 反作用力动画的火箭筒 00:10:36.338 --> 00:10:38.898 这个动画由几个部分组成 00:10:38.898 --> 00:10:47.969 首先检查输入,当按下Fire键时 产生一个火箭,播放音效并触发火箭动画播放 00:10:47.969 --> 00:10:49.969 让我们进一步分解这些步骤 00:10:49.969 --> 00:10:57.677 为了可以播放其他动画(跑步)时同时播放火箭发射 我们在动画控制器建立了Shooting的动画层 00:10:57.677 --> 00:11:06.980 将Weight属性设为1,可以 完全覆盖基本层(Base Layer)所有的动作 00:11:20.499 --> 00:11:27.351 我们可以从任何状态中用程序 触发Shoot参数发射动画 00:11:27.351 --> 00:11:30.543 来看看负责这工作的Gun脚本 00:11:32.700 --> 00:11:37.402 你可以看到我们写了驱动事件 触发Shoot为True 00:11:37.402 --> 00:11:45.511 触发后会打开,在下一格重置为关 就可以重复使用,对于射击动作最好用 00:11:46.011 --> 00:11:50.673 除了设定动画,我们也从脚本中发射火箭 00:11:50.673 --> 00:12:00.555 播放音效后根据角色的方向 产生火箭并给它一个X轴的正或负速度 00:12:01.276 --> 00:12:05.294 这个Gun脚本被放在主角身上的空物件 00:12:05.294 --> 00:12:11.663 像这样将脚本放到一个空对象上 可以轻易的定位火箭发射位置 00:12:11.663 --> 00:12:20.010 我们将对象放到火箭筒发射口 然后以他自己的坐标当作发射点 00:12:40.248 --> 00:12:46.804 火箭本身有2D刚体 我们给它一个速度让它移动 00:12:46.804 --> 00:12:51.096 它也有火焰喷射动画和粒子系统做的烟雾 00:12:52.826 --> 00:12:56.482 粒子系统也接受新的Sprite图片 00:12:56.482 --> 00:13:04.149 所以可以将烟雾的图片切好后加到材质 并指定到粒子系统的Texture Sheet Animation 00:13:04.149 --> 00:13:08.232 就有烟雾特效让粒子系统发射 00:13:16.122 --> 00:13:22.935 当火箭命中敌人或环境时 火箭本身会引起爆炸并被摧毁 00:13:22.935 --> 00:13:27.731 爆炸是我们制作的爆炸动画对象 00:13:27.731 --> 00:13:33.699 排序位置在前景的最后面 00:13:36.174 --> 00:13:44.576 要建立这类动画,可以从项目点选图片 然后在属性Sprite Mode选择Multiple 00:13:44.576 --> 00:13:49.757 这功能允许我们编辑图片 手动或是自动裁切图片大小 00:13:49.757 --> 00:13:52.406 一旦完成裁切后 00:13:52.406 --> 00:13:58.765 只需要点击Apply Unity会自动产生图片并作为子对象 00:13:59.707 --> 00:14:01.693 这就是火箭制作过程 00:14:01.693 --> 00:14:06.533 稍后我们将在影片中讨论 杀死敌人的动画技法 00:14:07.102 --> 00:14:12.194 现在先让我们回到主角 看看如何处理血条补血和扣血 00:14:12.194 --> 00:14:18.548 血条被定义为一个浮点数(Float) 每次碰到敌人就会呼叫TakeDamage函式 00:14:18.548 --> 00:14:25.347 为了避免触发太快造成死亡 我们用repeatDamagePeriod来间隔触发时间 00:14:26.524 --> 00:14:31.136 为了让角色显示受伤 并容易从敌人手中逃脱 00:14:31.136 --> 00:14:34.847 我们建立了受伤的动作 并在物理上弹飞主角 00:14:34.847 --> 00:14:39.540 要做到这点,TakeDamage函式 会阻止角色跳跃 00:14:39.540 --> 00:14:42.125 并从主角与敌人之间找到一个向量位置 00:14:42.125 --> 00:14:46.125 指定一个物理力量往指定方向击退 00:14:46.125 --> 00:14:55.323 hurtForce是一个全局变量,可以随时从接口调整 而不用从脚本里调整 00:14:55.323 --> 00:15:02.209 除了击退主角之外,我们同时 也扣掉角色的血量并更新血条 00:15:02.209 --> 00:15:09.825 为了呈现扣血,我们把血条的宽度缩减 用一个公式计算让绿色转变到红色 00:15:09.825 --> 00:15:14.640 透过当下的血量和总量算出一个百分比 00:15:14.640 --> 00:15:21.744 血条是由两个图片组成 一个显示血量,另一个显示外框 00:15:21.744 --> 00:15:25.954 这也是在Photoshop里做的 然后输出两个单独的图片 00:15:25.954 --> 00:15:34.053 导入图形的时候,设定图形轴心在左边 所以当它按比例减少时,就会往左缩 00:15:48.573 --> 00:15:54.573 这两个图片放在一个空对象底下 给予一个简单脚本,让它显示在角色头上 00:15:54.573 --> 00:15:58.621 将血条位置设定与角色相同 00:15:58.621 --> 00:16:02.621 并加上偏移用的全局变量 好在检视接口进行调整 00:16:16.215 --> 00:16:22.629 当主角血量为0时,设定碰撞体的isTrigger = true 主角就会往下跌到水上 00:16:22.629 --> 00:16:28.194 同时将主角排序推到UI层上 主角会移到画面最上层 00:16:28.194 --> 00:16:31.594 UI层是我们制作的层 是用来表示像UI的前面的对象 00:16:31.594 --> 00:16:34.223 当脚色死亡时,我们有两个动画 00:16:34.223 --> 00:16:38.631 一个叫Death,会失去帽子和枪 另外一个叫Falling 00:16:38.631 --> 00:16:47.239 用Exit Time当作动画的切换条件 一旦Death播完就会切到Falling动画 00:16:50.778 --> 00:16:55.000 最后,在播放死亡动画时 为了阻止玩家移动角色或射击 00:16:55.000 --> 00:16:58.340 我们会禁用PlayerControl和Gun脚本 00:16:58.340 --> 00:17:05.040 由于Die函式是全局可以从任何地方呼叫 例如玩家掉入水中 00:17:05.040 --> 00:17:12.463 要在主角接触水面时重置游戏,我们 用一个由触发器和脚本组成的KillTrigger对象 00:17:12.463 --> 00:17:17.512 在大多的情况下 Remover脚本移除掉入河中的敌人 00:17:17.512 --> 00:17:21.442 并播放一个水花动画和音效 00:17:21.442 --> 00:17:24.001 但如果是主角被触发器侦测到时 00:17:24.001 --> 00:17:27.092 就会呼叫PlayerHealth脚本里的Die函式 00:17:27.092 --> 00:17:34.527 并禁用CameraTracking同时将角色移出屏幕 并呼叫co-routiene函数(停止2秒) 00:17:34.527 --> 00:17:36.527 然后重生在出生点 00:17:37.079 --> 00:17:39.079 接下来焦点转移到角色生存 00:17:39.079 --> 00:17:42.481 来看看它是如何生存 和我们给予它甚么生存工具 00:17:42.481 --> 00:17:49.911 游戏中有两种帮助玩家的补给箱 一种箱子是炸弹,另一种可以补血 00:17:50.411 --> 00:17:55.695 补给箱由箱子和降落伞两个部分组成 00:17:58.046 --> 00:18:03.768 这两个元素放入一个空白对象 我们就可以一起触发动画 00:18:03.768 --> 00:18:08.476 我们定位这两个图片 降落伞的轴心位于父对象的中心 00:18:09.045 --> 00:18:15.307 这样动画可以左右摇摆 让降落伞是浮在空中的感觉 00:18:15.307 --> 00:18:19.307 然后增加一个刚体让它有重力往下掉 00:18:19.307 --> 00:18:24.962 箱子增加碰撞体用来探测它的着陆时机 和玩家捡起的时机 00:18:24.962 --> 00:18:30.513 着陆之后 播放第二段动画让降落伞消失 00:18:30.513 --> 00:18:34.916 跟游戏其他地方一样 动画器控制对象的状态 00:18:34.916 --> 00:18:38.916 我们可以看到预设的情况下 它会播放FloatDown动画 00:18:38.916 --> 00:18:43.472 然后当Land = True时会切换到着陆状态 00:18:43.972 --> 00:18:49.732 在脚本里,我们使用onTriggerEnter函数 透过标记来检测是否碰到地面 00:18:49.732 --> 00:18:55.098 我们也将补给箱从父对象中分离 并给它一个刚体 00:18:55.098 --> 00:19:00.624 它就可以和环境互动 比如降落在一个斜坡上就会斜停在坡上 00:19:00.624 --> 00:19:03.672 接下来看看炸弹 00:19:03.672 --> 00:19:08.475 捡起炸弹箱的动作是箱子上的 BombPickup脚本处理的 00:19:08.475 --> 00:19:16.739 透过角色身上的LayBombs脚本 增减主角拥有的炸弹数量 00:19:17.557 --> 00:19:25.557 LayBombs脚本负责检查是否携带着炸弹 并负责产生并放置炸弹 00:19:27.424 --> 00:19:36.147 炸弹设有定时装置,在爆炸之前 透过BombDetonation里的yield倒数计时 00:19:36.799 --> 00:19:39.545 爆炸函式执行几个动作 00:19:39.545 --> 00:19:43.797 它会重置bombLaid参数 允许产生另外一个炸弹箱 00:19:43.797 --> 00:19:49.797 它会通知产生器补充新的炸弹箱 并炸死范围内的敌人 00:19:50.518 --> 00:19:53.058 来看看最后一部分怎么运作的 00:19:53.058 --> 00:19:57.180 因为炸弹对敌人来说是致命的 不管他们的生命值剩下多少 00:19:57.180 --> 00:20:03.470 我们用Physics.OverlapCircleAll方法收集 在爆炸范围内所有标记为敌人的对象 00:20:03.470 --> 00:20:06.612 然后为每一个敌人执行循环 00:20:06.612 --> 00:20:15.542 设定他们的血量为0 从爆炸地点到敌人算出一个向量并施加外力 00:20:16.304 --> 00:20:21.381 一旦循环跑完,就可以播放视觉效果 00:20:21.381 --> 00:20:25.907 播放一段音效同时摧毁炸弹 00:20:26.875 --> 00:20:29.252 爆炸视觉效果有两部分 00:20:29.252 --> 00:20:33.583 主要部份是一个简单的圆形 短暂的出现后摧毁 00:20:33.583 --> 00:20:39.583 第二部分是星星状的粒子系统 重复用相同图片呈现火箭爆炸 00:20:42.265 --> 00:20:51.735 效率上我们保持粒子系统持续在场景中 需要时我们用程序移动到指定位置播放 00:20:52.511 --> 00:20:56.511 这样可以让粒子系统存在内存里 使游戏比较有效率 00:20:57.011 --> 00:21:04.668 这么做主要是因为这个范例 同时只会有一个爆炸在场景中 00:21:04.668 --> 00:21:07.794 因为玩家只能一次丢一个炸弹 00:21:07.794 --> 00:21:14.936 这就是为什么将粒子系统保持在场景中 并重复播放的原因,比起建立后移除有效率 00:21:15.714 --> 00:21:21.618 但如果是火箭爆炸,因为可以重复发射 因此需要建立后移除 00:21:22.118 --> 00:21:26.118 让我们看看主角杀死敌人 怎么计算分数 00:21:26.618 --> 00:21:35.528 这分为两个部分,动画显示获得100分 以及增加UI的分数计算 00:21:35.528 --> 00:21:40.193 分数动画由1和0两个数字组成 00:21:40.193 --> 00:21:42.872 将它们放到场景中的空白对象 00:21:42.872 --> 00:21:49.186 给予一个简单的得分动画 并用程序让它们在动画完成后消失 00:21:49.186 --> 00:21:55.186 我们放置摧毁脚本在动画事件尾端 00:22:06.142 --> 00:22:13.703 ScoreUI单纯是个GUI文字组件 带有管理玩家分数的脚本 00:22:13.703 --> 00:22:20.980 Score是全局变量,代表随时可以 检查当敌人被杀死时增加100分 00:22:20.980 --> 00:22:24.980 说到敌人,让我们仔细看看他们 00:22:25.480 --> 00:22:28.260 在我们的游戏里,有两种类型外星敌人 00:22:28.260 --> 00:22:30.854 一种是绿皮肤的鼻涕虫 00:22:30.854 --> 00:22:34.563 另一种是会搭着飞船保护自己 的智能型外星怪物 00:22:34.563 --> 00:22:36.563 这些角色会共享一种脚本 00:22:36.563 --> 00:22:38.563 因为他们行为相似 00:22:38.563 --> 00:22:45.765 我们可以检视它们的全局变量 并设定不同的移动速度和生命 00:22:46.638 --> 00:22:49.093 每个敌人都有自己的移动动画 00:22:49.093 --> 00:22:54.444 鼻涕虫有一个可以活动的尾巴 飞船内的敌人会前后摇摆移动 00:22:55.994 --> 00:23:01.994 对鼻涕虫来说,我们汇入图形 并把尾巴切为独立图形 00:23:01.994 --> 00:23:07.475 这样我们就可以单独缩放它 不会影响到整个图片 00:23:07.475 --> 00:23:14.124 轴心设定到右边 我们可以漂亮的伸展收缩尾巴 00:23:16.475 --> 00:23:19.918 上下移动眼睑 00:23:19.918 --> 00:23:24.859 然后使用Z轴来排序 眼睛就会在眼睑底下了 00:23:24.859 --> 00:23:26.859 就可以制作眨眼动画 00:23:28.865 --> 00:23:34.046 第二个外星人的动画要简单的多 我们只需要前后转动它 00:23:35.798 --> 00:23:41.229 关于这些敌人的移动技术 我们透过改变刚体的速率来移动它们 00:23:41.229 --> 00:23:47.826 当它们遇到一个墙壁这样的障碍物时 会呼叫Physics.OverlapPoint函式来检测 00:23:47.826 --> 00:23:55.850 检查是否有重迭到像是 墙壁和两边的塔被标记的障碍物 00:23:55.850 --> 00:23:59.161 当函式侦测到时,就会呼叫Flip函式 00:23:59.161 --> 00:24:04.070 函式会翻转敌人的X轴缩放 让它转到不同方向 00:24:04.070 --> 00:24:11.036 要杀死敌人,当敌人和火箭相撞时 在撞击时会呼叫Hurt函式 00:24:14.962 --> 00:24:19.213 这个函式我们从敌人身上扣1点血 00:24:19.213 --> 00:24:23.213 并持续呼叫函式保持敌人持续扣血 00:24:23.213 --> 00:24:27.124 如果血条降到0,就会呼叫死亡函式 00:24:31.229 --> 00:24:33.916 当他们死后,就会执行一些函式 00:24:33.916 --> 00:24:39.916 会先停用所有的图形渲染 因为2D角色大多都有动画 00:24:40.941 --> 00:24:46.941 这是为了把动画对象换成单张死亡图片 00:24:47.745 --> 00:24:54.165 我们在图形渲染器将图片改为deadEnemy 00:24:54.165 --> 00:24:58.165 然后我们帮Score全局变量增加100 00:24:58.165 --> 00:25:03.534 然后增加扭转让他们死亡时扭曲 00:25:04.448 --> 00:25:08.881 因此我们要让这些敌人死后 掉入环境的河中 00:25:08.881 --> 00:25:13.589 我们找到对象上所有碰撞体 并设定IsTrigger = True 00:25:13.589 --> 00:25:17.417 这样他们就会穿过所有环境往下掉 00:25:17.417 --> 00:25:25.470 然后播放死亡音效之后展示一个分数动画 00:25:27.876 --> 00:25:29.876 要将已死亡的敌人从场景中移除 00:25:29.876 --> 00:25:31.876 我们使用killTregger对象 00:25:31.876 --> 00:25:34.762 和前面所说的一样 00:25:34.762 --> 00:25:36.762 当任何角色接触它时 00:25:36.762 --> 00:25:39.950 将会引起一个水花动画,并移除该对象 00:25:39.950 --> 00:25:45.950 它们撞击水面并播放 一段附在水花动画的音效 00:25:45.950 --> 00:25:50.634 所以当我们产生水花动画时 同时也听到音效 00:25:55.153 --> 00:25:59.153 要完成游戏关卡 我们也用一些移动背景来装饰 00:25:59.153 --> 00:26:02.302 为了让游戏环境更显动态 00:26:02.302 --> 00:26:07.125 我们添加了一些飞翔的天鹅 以及沿着河岸开的公交车和出租车 00:26:07.125 --> 00:26:16.051 首先是天鹅,它是在Photoshop里面画好后 用Multiple Sprite导入图片 00:26:16.051 --> 00:26:20.800 Unity会自动裁切天鹅的每个图片 00:26:20.800 --> 00:26:24.579 分为不同的图导入 并把原图当作父对象放在底下 00:26:24.579 --> 00:26:32.346 因为这是个动画组合,可以将所有的图片 一起拖到场景中,让Unity帮我们生成动画 00:26:32.346 --> 00:26:37.759 瞧,天鹅的动画已经准备好了 00:26:37.759 --> 00:26:43.369 然后给天鹅一个刚体 让我们可以控制速度飞过屏幕 00:26:43.369 --> 00:26:47.334 和公交车和出租车一样,天鹅已被存为预制对象 00:26:49.257 --> 00:26:55.257 公交车和出租车作法只需要 在汇入图形时分开车身和车轮 00:26:55.257 --> 00:26:58.392 并制作一个简单的摆动动画 00:26:58.392 --> 00:27:04.376 相同指定2D刚体到车子上 就能够驱动他们在屏幕上跑 00:27:07.279 --> 00:27:14.271 公交车、出租车和天鹅这三个物件 我们用一个重复执行的脚本来制造它们 00:27:14.271 --> 00:27:21.838 BackgroundPropsSpawner脚本 同时也处理出生位置,出生频率并给予速度 00:27:21.838 --> 00:27:30.521 代表我们可以用这个脚本应用在三种对象 默认出生点和属性 00:27:30.521 --> 00:27:33.854 要了解更多的细节,可以查看脚本中的说明 00:27:33.854 --> 00:27:40.409 最后,要了解更多的背景动态 我们使用了移动的云朵、流动的河水和烟雾 00:27:41.323 --> 00:27:50.004 我们在空白对象下放两个背景图片 并使这些图片缓慢飞过屏幕 00:27:50.004 --> 00:27:54.652 因为这是个无限循环 所以动画永远不会停 00:27:59.185 --> 00:28:01.031 这就是我们游戏的制作过程 00:28:01.031 --> 00:28:05.516 我们希望这个教学让你 对如何用Unity开发2D游戏有一定了解 00:28:05.516 --> 00:28:08.971 未来我们也会制作更简单的教学 00:28:08.971 --> 00:28:14.959 也期待你们对于Unity4.3的反应 迫不及待想看看你们的2D产品 00:28:14.959 --> 00:28:16.487 谢谢观看