-
Unity 4.3 我们发布了第一阶段的2D工具
-
为此,我们用这个工具做了一个2D范例
-
这个2D范例叫做"铁桥塔防"
-
描述伦敦铁桥被外星人入侵的故事
-
范例完全用2D图片和物理来呈现
让你了解这些元素如何在Unity里组合
-
影片会说明范例里的背景、前景、角色、特效
镜头追迹、动作和脚本程序是如何制作的
-
开始之前,先来聊聊基本的Unity 2D工作
-
首先,当要制作2D项目,你应该先设定工作环境为2D
-
可以在建立新项目时在下拉选单设定
-
或是在开发中到Edit - Project Settings - Editor调整
-
这代表预设情况下,输入的材质会
被视为2D图片,场景视图也会预设为2D
-
这个新的2D模式会采用完全的
正视图视角来呈现你的2D游戏
-
同时也会把右上角的3D小图示都隐藏
让工作空间更大
-
除此之外,Unity 2D的工作流程
是和现有的3D流程整合在一起的
-
如果你已经会操作原本的Unity
那Unity 2D会很好上手
-
值得一提的是,你也可以混搭2D和3D共享
-
所以如果你想要有3D元素在你的2D游戏里
或2D元素在3D游戏里都没有问题
-
现在来看看范例如何建立一个关卡
-
我们一开始勾勒关卡设计雏形
然后到Photoshop里面去把每个图层做出来
-
然后输出这些图层
成为新的Sprite类型导入Unity
-
为了呈现出背景的视差,我们做了一些
背景元素在Sorting Layer里
-
这是一个2D工具的新功能
-
当所有背景指定到这一层后
我们可以在图片着色器的图层排序它们
-
调好位置之后也可以把图层锁定不能编辑
-
这样的话我们编辑前景元素的时候
就不用担心会不小心动到背景元素
-
可以从接口右上方的图层选单来设定
-
由于背景只是装饰用的,所以
并不需要在图片上放任何组件
-
将它们放到一个空的对象里
-
并放入一个叫做叫做
BackgroundParallax的脚本来处里视差
-
更多的细节可以详查这个已经批注的脚本
-
接下来制作角色活动的前景空间
-
我们设计了伦敦铁桥和降落在中间的飞碟
-
主角处于一个敌人从天而降并到处乱窜的环境
-
因此,每一个前景元素都需要
碰撞体(Collider)来让主角在上面行走
-
大多数环境用方体碰撞就可以
除了外型比较复杂的飞碟
-
Unity提供多边形碰撞体(Polygon Collider)
可以根据图片外型自动产生多边形碰撞体
-
甚至可以调整碰撞体的外型
-
你可以新增、移动或删除节点
调整到更适合行走的外型
-
为了排序前景元素我们建立了前景层
设定显示在背景之前
-
接下来看看主角
-
我们的主角也是在Photoshop里面设计的
一个四肢独立类似卡通主角雷曼的角色
-
另外一个2D工具的新功能
-
是一个以图表化的动画工具
可以在Photoshop里绘制每一节点的图
-
后面我们会介绍如何用这方法
制造我们的天鹅
-
因为身体部位分开比较好控制动画
因此我们希望独立每个身体部位
-
所以我们将身体部位独立切开
好让Unity在输入时容易拆离它们
-
这代表我们可以为图片单独制作动作
-
把这些部位放入建好的角色层
然后改变Z轴深度来改变前后顺序
-
把这些图片都放入一个有控制脚本
碰撞体、物理设定等等的对象
-
一旦做到这里,就可以到动画窗口给予图片动作
建立待机、跑、跳、射击和死亡的动画
-
使用动画窗口里新的分镜表功能
就可以简单制作动作
-
我们在父对象建立一个动画组件
然后针对每一个子对象建立影格
-
移动指标到想要的影格后调整角色部位
就会自动把变量录到影格上
-
可随时切换分镜表和动画曲线
使得它更容易调整设计
-
这些动作建立好之后我们可以
帮我们的角色设计控制状态
-
让我们用程序呼叫角色执行各种动作
-
因为不是驱动3D骨架,所以取消打勾Root Motion
-
也可以打勾Animate Physics如果
动画要和物理行为相互作用
-
为了在场景走动,主角脚上有圆形碰撞体
和一个包覆整个身体的方形碰撞体
-
这样他可以平顺地行走和跳下场景
跳起来的时候头部也可以判定撞到
-
为了控制角色动作,我们写了
一个脚本透过2D物理引擎来移动
-
这代表在游戏里面可以指定主角和敌人
让游戏动态更丰富的物理行为
-
我们用PlayerControl脚本来判断角色的输入
-
我们在此指定物理移动速度
同时也把输入的值送到动画控制器
-
判定播放哪些动画以及
顺畅的播放分镜表上图片的转变
-
使用动画控制建立图片动态最大的好处是
-
可以调整动画速度用来搭配物理速度
不需要额外再作任何判定
-
FixedUpdate函式会检查每一步物理运算
-
在这里我们第一件要做的事情是
把输入的水平值传给动画的速度参数
-
在我们的状态设定里
待机状态到跑动需要速度参数大于0.1
-
当值成立时,动画就会从待机切到跑步
-
要让角色移动,让它有Rigidbody2D组件
就可以为它加力道移动
-
同时我们也根据输入的水平值是
大于0或小于0来处理角色面朝的方向
-
这是因为在Unity里,按住左键会传回-1
而按住右键会传回+1
-
根据输入值呼叫一个简单的翻转函数
来翻转角色的X轴缩放,让角色面向反方向
-
为了判定角色是否着地
我们新增了一个Ground图层
-
并指定给全部可行走的前景物件
-
然后使用2D里面的Linecast函数
检查Ground图层是否和角色的脚接触
-
为了让制作更容易,我们建立了
一个空白的对象当作检查地面的标准点
-
在该对象上增加一个小图示
我们就可以控制角色到地面的距离
-
就游戏角度来看
角色在地面时只能做跳的动作
-
更多关于角色控制的信息
可以查看范例脚本里面的说明
-
影片稍后也会讨论角色的武器
-
接下来看看相机如何追踪角色
-
跟3D游戏一样,在2D游戏里
镜头运镜也左右着游戏体验
-
要呈现经典的2D游戏运镜
我们参考了2D游戏经典大作
-
任天堂或超任的超级玛莉欧的镜头运作
-
在超级玛莉欧世界里镜头会水平移动
除了封闭的空间或关卡边缘
-
在这两类区域里角色小幅移动
镜头不会追踪
-
一旦角色移出区域
镜头又会开始追踪角色
-
超级玛莉欧的相机
用特定高度来进行垂直判定
-
但我们的游戏没有往上的长度
比较像动作平台,所以不需要这类设定
-
因此我们的相机在垂直判定
采用了和水平一样的方法
-
请看看主相机里的CameraFollow脚本
了解镜头追踪更完整的写法和批注
-
游戏中有许多特效
但最重要的是主角杀死外星人的能力
-
主角会发射一个具有
反作用力动画的火箭筒
-
这个动画由几个部分组成
-
首先检查输入,当按下Fire键时
产生一个火箭,播放音效并触发火箭动画播放
-
让我们进一步分解这些步骤
-
为了可以播放其他动画(跑步)时同时播放火箭发射
我们在动画控制器建立了Shooting的动画层
-
将Weight属性设为1,可以
完全覆盖基本层(Base Layer)所有的动作
-
我们可以从任何状态中用程序
触发Shoot参数发射动画
-
来看看负责这工作的Gun脚本
-
你可以看到我们写了驱动事件
触发Shoot为True
-
触发后会打开,在下一格重置为关
就可以重复使用,对于射击动作最好用
-
除了设定动画,我们也从脚本中发射火箭
-
播放音效后根据角色的方向
产生火箭并给它一个X轴的正或负速度
-
这个Gun脚本被放在主角身上的空物件
-
像这样将脚本放到一个空对象上
可以轻易的定位火箭发射位置
-
我们将对象放到火箭筒发射口
然后以他自己的坐标当作发射点
-
火箭本身有2D刚体
我们给它一个速度让它移动
-
它也有火焰喷射动画和粒子系统做的烟雾
-
粒子系统也接受新的Sprite图片
-
所以可以将烟雾的图片切好后加到材质
并指定到粒子系统的Texture Sheet Animation
-
就有烟雾特效让粒子系统发射
-
当火箭命中敌人或环境时
火箭本身会引起爆炸并被摧毁
-
爆炸是我们制作的爆炸动画对象
-
排序位置在前景的最后面
-
要建立这类动画,可以从项目点选图片
然后在属性Sprite Mode选择Multiple
-
这功能允许我们编辑图片
手动或是自动裁切图片大小
-
一旦完成裁切后
-
只需要点击Apply
Unity会自动产生图片并作为子对象
-
这就是火箭制作过程
-
稍后我们将在影片中讨论
杀死敌人的动画技法
-
现在先让我们回到主角
看看如何处理血条补血和扣血
-
血条被定义为一个浮点数(Float)
每次碰到敌人就会呼叫TakeDamage函式
-
为了避免触发太快造成死亡
我们用repeatDamagePeriod来间隔触发时间
-
为了让角色显示受伤
并容易从敌人手中逃脱
-
我们建立了受伤的动作
并在物理上弹飞主角
-
要做到这点,TakeDamage函式
会阻止角色跳跃
-
并从主角与敌人之间找到一个向量位置
-
指定一个物理力量往指定方向击退
-
hurtForce是一个全局变量,可以随时从接口调整
而不用从脚本里调整
-
除了击退主角之外,我们同时
也扣掉角色的血量并更新血条
-
为了呈现扣血,我们把血条的宽度缩减
用一个公式计算让绿色转变到红色
-
透过当下的血量和总量算出一个百分比
-
血条是由两个图片组成
一个显示血量,另一个显示外框
-
这也是在Photoshop里做的
然后输出两个单独的图片
-
导入图形的时候,设定图形轴心在左边
所以当它按比例减少时,就会往左缩
-
这两个图片放在一个空对象底下
给予一个简单脚本,让它显示在角色头上
-
将血条位置设定与角色相同
-
并加上偏移用的全局变量
好在检视接口进行调整
-
当主角血量为0时,设定碰撞体的isTrigger = true
主角就会往下跌到水上
-
同时将主角排序推到UI层上
主角会移到画面最上层
-
UI层是我们制作的层
是用来表示像UI的前面的对象
-
当脚色死亡时,我们有两个动画
-
一个叫Death,会失去帽子和枪
另外一个叫Falling
-
用Exit Time当作动画的切换条件
一旦Death播完就会切到Falling动画
-
最后,在播放死亡动画时
为了阻止玩家移动角色或射击
-
我们会禁用PlayerControl和Gun脚本
-
由于Die函式是全局可以从任何地方呼叫
例如玩家掉入水中
-
要在主角接触水面时重置游戏,我们
用一个由触发器和脚本组成的KillTrigger对象
-
在大多的情况下
Remover脚本移除掉入河中的敌人
-
并播放一个水花动画和音效
-
但如果是主角被触发器侦测到时
-
就会呼叫PlayerHealth脚本里的Die函式
-
并禁用CameraTracking同时将角色移出屏幕
并呼叫co-routiene函数(停止2秒)
-
然后重生在出生点
-
接下来焦点转移到角色生存
-
来看看它是如何生存
和我们给予它甚么生存工具
-
游戏中有两种帮助玩家的补给箱
一种箱子是炸弹,另一种可以补血
-
补给箱由箱子和降落伞两个部分组成
-
这两个元素放入一个空白对象
我们就可以一起触发动画
-
我们定位这两个图片
降落伞的轴心位于父对象的中心
-
这样动画可以左右摇摆
让降落伞是浮在空中的感觉
-
然后增加一个刚体让它有重力往下掉
-
箱子增加碰撞体用来探测它的着陆时机
和玩家捡起的时机
-
着陆之后
播放第二段动画让降落伞消失
-
跟游戏其他地方一样
动画器控制对象的状态
-
我们可以看到预设的情况下
它会播放FloatDown动画
-
然后当Land = True时会切换到着陆状态
-
在脚本里,我们使用onTriggerEnter函数
透过标记来检测是否碰到地面
-
我们也将补给箱从父对象中分离
并给它一个刚体
-
它就可以和环境互动
比如降落在一个斜坡上就会斜停在坡上
-
接下来看看炸弹
-
捡起炸弹箱的动作是箱子上的
BombPickup脚本处理的
-
透过角色身上的LayBombs脚本
增减主角拥有的炸弹数量
-
LayBombs脚本负责检查是否携带着炸弹
并负责产生并放置炸弹
-
炸弹设有定时装置,在爆炸之前
透过BombDetonation里的yield倒数计时
-
爆炸函式执行几个动作
-
它会重置bombLaid参数
允许产生另外一个炸弹箱
-
它会通知产生器补充新的炸弹箱
并炸死范围内的敌人
-
来看看最后一部分怎么运作的
-
因为炸弹对敌人来说是致命的
不管他们的生命值剩下多少
-
我们用Physics.OverlapCircleAll方法收集
在爆炸范围内所有标记为敌人的对象
-
然后为每一个敌人执行循环
-
设定他们的血量为0
从爆炸地点到敌人算出一个向量并施加外力
-
一旦循环跑完,就可以播放视觉效果
-
播放一段音效同时摧毁炸弹
-
爆炸视觉效果有两部分
-
主要部份是一个简单的圆形
短暂的出现后摧毁
-
第二部分是星星状的粒子系统
重复用相同图片呈现火箭爆炸
-
效率上我们保持粒子系统持续在场景中
需要时我们用程序移动到指定位置播放
-
这样可以让粒子系统存在内存里
使游戏比较有效率
-
这么做主要是因为这个范例
同时只会有一个爆炸在场景中
-
因为玩家只能一次丢一个炸弹
-
这就是为什么将粒子系统保持在场景中
并重复播放的原因,比起建立后移除有效率
-
但如果是火箭爆炸,因为可以重复发射
因此需要建立后移除
-
让我们看看主角杀死敌人
怎么计算分数
-
这分为两个部分,动画显示获得100分
以及增加UI的分数计算
-
分数动画由1和0两个数字组成
-
将它们放到场景中的空白对象
-
给予一个简单的得分动画
并用程序让它们在动画完成后消失
-
我们放置摧毁脚本在动画事件尾端
-
ScoreUI单纯是个GUI文字组件
带有管理玩家分数的脚本
-
Score是全局变量,代表随时可以
检查当敌人被杀死时增加100分
-
说到敌人,让我们仔细看看他们
-
在我们的游戏里,有两种类型外星敌人
-
一种是绿皮肤的鼻涕虫
-
另一种是会搭着飞船保护自己
的智能型外星怪物
-
这些角色会共享一种脚本
-
因为他们行为相似
-
我们可以检视它们的全局变量
并设定不同的移动速度和生命
-
每个敌人都有自己的移动动画
-
鼻涕虫有一个可以活动的尾巴
飞船内的敌人会前后摇摆移动
-
对鼻涕虫来说,我们汇入图形
并把尾巴切为独立图形
-
这样我们就可以单独缩放它
不会影响到整个图片
-
轴心设定到右边
我们可以漂亮的伸展收缩尾巴
-
上下移动眼睑
-
然后使用Z轴来排序
眼睛就会在眼睑底下了
-
就可以制作眨眼动画
-
第二个外星人的动画要简单的多
我们只需要前后转动它
-
关于这些敌人的移动技术
我们透过改变刚体的速率来移动它们
-
当它们遇到一个墙壁这样的障碍物时
会呼叫Physics.OverlapPoint函式来检测
-
检查是否有重迭到像是
墙壁和两边的塔被标记的障碍物
-
当函式侦测到时,就会呼叫Flip函式
-
函式会翻转敌人的X轴缩放
让它转到不同方向
-
要杀死敌人,当敌人和火箭相撞时
在撞击时会呼叫Hurt函式
-
这个函式我们从敌人身上扣1点血
-
并持续呼叫函式保持敌人持续扣血
-
如果血条降到0,就会呼叫死亡函式
-
当他们死后,就会执行一些函式
-
会先停用所有的图形渲染
因为2D角色大多都有动画
-
这是为了把动画对象换成单张死亡图片
-
我们在图形渲染器将图片改为deadEnemy
-
然后我们帮Score全局变量增加100
-
然后增加扭转让他们死亡时扭曲
-
因此我们要让这些敌人死后
掉入环境的河中
-
我们找到对象上所有碰撞体
并设定IsTrigger = True
-
这样他们就会穿过所有环境往下掉
-
然后播放死亡音效之后展示一个分数动画
-
要将已死亡的敌人从场景中移除
-
我们使用killTregger对象
-
和前面所说的一样
-
当任何角色接触它时
-
将会引起一个水花动画,并移除该对象
-
它们撞击水面并播放
一段附在水花动画的音效
-
所以当我们产生水花动画时
同时也听到音效
-
要完成游戏关卡
我们也用一些移动背景来装饰
-
为了让游戏环境更显动态
-
我们添加了一些飞翔的天鹅
以及沿着河岸开的公交车和出租车
-
首先是天鹅,它是在Photoshop里面画好后
用Multiple Sprite导入图片
-
Unity会自动裁切天鹅的每个图片
-
分为不同的图导入
并把原图当作父对象放在底下
-
因为这是个动画组合,可以将所有的图片
一起拖到场景中,让Unity帮我们生成动画
-
瞧,天鹅的动画已经准备好了
-
然后给天鹅一个刚体
让我们可以控制速度飞过屏幕
-
和公交车和出租车一样,天鹅已被存为预制对象
-
公交车和出租车作法只需要
在汇入图形时分开车身和车轮
-
并制作一个简单的摆动动画
-
相同指定2D刚体到车子上
就能够驱动他们在屏幕上跑
-
公交车、出租车和天鹅这三个物件
我们用一个重复执行的脚本来制造它们
-
BackgroundPropsSpawner脚本
同时也处理出生位置,出生频率并给予速度
-
代表我们可以用这个脚本应用在三种对象
默认出生点和属性
-
要了解更多的细节,可以查看脚本中的说明
-
最后,要了解更多的背景动态
我们使用了移动的云朵、流动的河水和烟雾
-
我们在空白对象下放两个背景图片
并使这些图片缓慢飞过屏幕
-
因为这是个无限循环
所以动画永远不会停
-
这就是我们游戏的制作过程
-
我们希望这个教学让你
对如何用Unity开发2D游戏有一定了解
-
未来我们也会制作更简单的教学
-
也期待你们对于Unity4.3的反应
迫不及待想看看你们的2D产品
-
谢谢观看