从零开始独立游戏开发学习笔记(二十三)--Unity学习笔记(十)--M_Studio教程2D入门

小小小小小狐狸
1. 物品收集
先加上樱桃,这个之前讲过就不说了。然后是樱桃的收集效果。
1.1 IsTrigger
首先得加上碰撞体,然后勾上 IsTrigger,因为我们想让这个碰撞体作为一个触发手段而不是物理效果。
1.2 tag
在 layer 左边还有一个 tag,也是用于给 objct 分类。不过两者侧重点不同,像是马上准备要做的碰撞效果 就是 tag 比较侧重的部分。之前讲的选中物体就是 layer 主场。
这里我们添加一个 collection 的 tag,给樱桃加上。
然后在 unity 里加一个新的内置方法,叫做 OnTriggerEnter2D,这个方法会在 trigger 碰撞发生时触发。参数为碰撞的物体。这里判断如果碰撞的物体的 tag 为 Collection 的时候销毁它。

1.3 物品收集
只是销毁当然不够,还需要增加收集的数量。这个很简单,给 player 加一个 cherry 变量,吃到樱桃的时候 + 1 即可。
1.4 关卡设计
然后就是自由发挥,把关卡画丰富一些。

2. bug 修复
2.1 撞墙不掉落
通过之前的流程做出来的游戏,小狐狸撞到墙后只要按着方向键不会掉落。原因是小狐狸移动的时候有一个向左/右的力,而这个力加上摩擦系数,就会产生垂直方向的摩擦力,因此小狐狸不会掉下去。
解决这个的方法当然是对摩擦力进行调整,为了调整摩擦力,需要用到 2D -> Physics Material 2D,也就是物理材质 2D。在 asset panel 新建这么一个材质。拖到小狐狸的脸部的 box collider 上,当然这是取巧之技,真实情况应该是在墙面上新建一个层赋予光滑,只是比较麻烦现在不做。
2.2 多级跳
现在小狐狸可以在空中跳且无限跳,这很不好。当然之后会介绍更好的方法,不过现在可以先通过判断是否在地面上来判断是否跳跃做一个简单的处理。
2.3 多次积分
有时候小狐狸收集到一个樱桃却加两分,这是因为我们给小狐狸设置了两个碰撞体,因此当某一帧这两个碰撞体恰好都碰撞了后就会触发两次 OnTriggerEnter2D。
当然你可能回想,可是我们第一次碰撞后就 Destroy 了啊?没错,但是 Unity 的 Destory 并不会在这一帧给你销毁掉,而是要等到下一帧。因此可以选择碰撞后将其 tag 设置为 Untagged,这样就可以避免第二次加分了。

3. UI
所有的 UI 都要在 canvas 上,因此首先创建的应该是一个 canvas。
双击 canvas 聚焦,会发现其在一个完全看不到游戏界面的地方,这是因为 UI 全部是在单独的界面。 新建几个 text 和 image,显示出一些 UI

然后在 player 里去改变这个值(也是为了取巧,真实情况写在 player 里并不好),在 player 里新建一个 Text 类型的变量(这个变量需要导入 UnityEngine.UI 库),然后运行的时候更改这个变量即可。
不过依然有一个问题,那就是当切换分辨率的时候,会发现 UI 的位置会换来换去。
3.1 锚点
进入 canvas 视角,选中一个 UI object,会发现屏幕中央有一个锚点:

这个锚点的意思就是这个 object 是按照和这个锚点的距离关系保持不变的。这时,选择 inspector 里上方的这个,这样就可以将其始终固定在左上角:

但是依然有问题,那就是调整到高分辨率(如 4K) 的时候,UI 会变得非常小,如果有点前端知识可以知道这是因为我们的 UI 用的是 px 为单位造成的,因此我们前往 canvas 的 inspector 里将 UI scale mode 更改为随着 screen size 而改变(类似于前端的 vh,vw 单位)

4.敌人
首先给一个简单的,碰到敌人就消灭的效果。做法和收集类似,不过敌人是有碰撞体的而不是 trigger,因此用得另一个方法,这个方法有一个明显的区别就是参数不是 collider 而是 collision,因此选取 tag 前摇先取得 gameobject,不过都在 collision 里可以直接访问因此也不麻烦。

当然这样很不好,我们想让角色在踩到敌人才会消灭。因此可以使用之前的 isFalling 来判断。当然这样也并不精确,依旧存在很多 bug,这是为了教程取舍。
4.1 弹回和硬直
再给角色添加一个碰撞后弹回的效果,当碰撞发生时,判断如果不是踩死敌人的话,就弹回对应方向一段距离。不过添加完弹回的代码后发现并不会运作,这是因为方向键一直按着的时候,角色会一直被赋予速度,覆盖掉弹回效果的速度。因此我们引入了硬直效果,当碰撞后赋值硬直,移动动画里判断当硬直的时候无法移动。

当然,效果依然还有问题,第一次碰撞后就无法行动了,这是自然,因为我们没有把硬直调回来。 方法是在 update 里加这么一段:

当速度的绝对值小于 0.1 的时候恢复硬直,也就是当弹回接近停止的时候恢复。
4.2 受击动画
除了 falling 状态的所有状态都可以变成 hurt 状态,结束后效果类似如下:

5. 简单敌人 AI
相当简单的 AI。
首先给青蛙添加脚本,之前都是在 component 里添加的,这样其实有一个不好,就是自动创建的脚本文件在最外层,还要手动拖到 Scripts 文件夹里,因此比较方便的是直接在文件夹里新建脚本,然后拖到青蛙组件或者hierarchy上即可。
然后我们需要给青蛙加一个左右自行移动的效果。老师给了其中一个方法, 当然真实情况有其他更好的方法,老师主要是为了介绍 unity 的一些特性而专门采用某些方法的。
像是这里的话,老师先是给 frog 增加了两个子物体(空物体),分别作为左右边界。那么当我们看向屏幕的时候,发现因为是空物体,屏幕上找不到位置,因此这里就引入了 icon 的概念:
5.1 icon
点击在 inspector 左上角的方块,可以给物体添加 icon。找不到 icon 的时候可以去 scene view 上方的 gizmos 列表里可以调整 3d icon 的大小,这个之前讲过。
5.2 debug 可以去 scene 里看
老师想着通过判断青蛙的位置和子物体的位置的对应来判断是否转向。但实际上发现并没有这样做。原因很简单,因为子物体跟着青蛙一起动了。
虽然这个 bug 很容易就能想到,但是这里老师让我们去 scene 里看,有玩的时候也可以转去 scene 里看。因为 scene 里细节很多,而且可以看到 icon。而 game view 里是看不到的。可以很直观地看到 icon 随着青蛙在动。
5.3 断绝继承关系
这里的解决方案就是在 start 时,断绝 left,right 与 frog 的继承关系。使用 DetachChildren 即可。
5.4 不断绝关系的方式
断绝后 hierarchy 上全是 left 和 right,虽然不影响游玩,退出游戏模式后也会返回。但是这样不好看,其实可以在一开始获得两个项目的位置后,直接将这两个项目销毁。
6. 青蛙动画
先给青蛙加上跳跃动画,按照之前的来,先做出一个只要碰到地面就会跳的效果。
6.1 event
在这之后开始介绍事件,因为要做出一个,掉落到地面后完成一个 idle 动画,再跳跃的效果。这个用之前的方式是不行的,因为要保证一整个 idle 动画完成,要在 idle 动画播放完后执行,于是 event 出现了。
这里我们把 move 从fixupdate 里移出来。让 idle 动画播放到最后时执行。这样就可以保证青蛙在 idle 动画时时不会移动和跳跃了。 跳跃动画以及动画的切换和之前一样。
7. 成果
