除了地面,地图上还会有很多装饰物体等等,比如箱子房子之类的,接下来我们对这种类型的物体进行设置。

三、装饰世界

        在 Project 窗口中,选择 Assets > Art > Sprites > Environment。选择 MetalCube 精灵,拖到Hierarchy窗口中,可以在Hierarchy中创建一个Boxes用来集中存储箱子。

        运行游戏我们发现,将Ruby移动到箱子上时它是一直在箱子上方的,我们需要调整图层设置伪3D。

        1.选择 Edit > Project Settings。

        2. 在左侧类别菜单中,单击 Graphics。

        3.在 Camera Settings 中,找到 Transparency Sort Mode 字段。此字段决定了精灵的绘制顺序。使用下拉菜单将此设置从 Default 更改为 Custom Axis。

unity2d 游戏制作 教程 unity制作2d游戏总结_unity2d 游戏制作 教程

         将x和z设置为0,y设置为1,红线处更改为Custom Axis(自定义轴)此设置告诉 Unity 在 y 轴上基于精灵的位置来绘制精灵。记得把地板都调成-1,不然会把所有的其他元素都覆盖在下面。

        这时候在运行就能发现在箱子后可以被覆盖,箱子前覆盖箱子了。

        找到点击Project中的MetalCube,在Inspector界面中将Pivot更改为bottom,这样就会将轴心置于精灵的底部,而不是先前的中部。然后我们点击Sprite Editor来调节遮罩范围。

unity2d 游戏制作 教程 unity制作2d游戏总结_游戏_02

          将遮罩调整为下图,点击右上角apply即可。

unity2d 游戏制作 教程 unity制作2d游戏总结_游戏引擎_03

         当我们需要重复使用一个调整好的对象,那么可以将他制作成预制件,每次使用就不需要重复设置了。

        在Assets文件夹下创建Prefabs文件夹专门存放预制件。将Hierarchy界面中设置好的对象如MetalCube拖入Project中的Prefabs文件夹中,可以看见Hierarchy中的MetalCube已经变成了蓝色,说明变成了预制件。

四、阻止移动

        Unity 有一个内置的物理系统,可以为你计算对象的移动和碰撞。在Project中找到Prefabs文件夹,将Hierarchy中的Ruby拖入变为预制件。双击进入预制件模式,在下方点击Add Component,搜索添加Rigidbody 2D。

unity2d 游戏制作 教程 unity制作2d游戏总结_unity2d 游戏制作 教程_04

         在Rigidbody 2D中,需要将重力设置为0,不然一运行游戏,Ruby就掉下去了。

unity2d 游戏制作 教程 unity制作2d游戏总结_游戏引擎_05

         再给Ruby添加Box Collider 2D组件,点击组件中的Edit Collider,对碰撞范围进行调整,控制在脚下就可以。

        给箱子也添加Box Collider 2D组件,调整碰撞范围,然后运行游戏,发现已经实现了碰撞,但是角色会歪掉。Rigidbody 2D中有固定的选项,如下图,勾选Freeze Rotation,即可锁定。

unity2d 游戏制作 教程 unity制作2d游戏总结_unity2d 游戏制作 教程_06

         但我们又发现,Ruby在接触到物体时一直在抽风,这是因为控制移动的代码写在update里,每次刷新是,它先会移动进物理里一点然后再被碰撞组件弹出去,所以出现了抽风的症状。

        要解决这个问题,我们只需要把控制角色移动改为控制刚体移动,移动刚体本身,这样就可以保证运动与碰撞是同步的。

        除了Update,unity还有一个FixedUpdate函数,直接影响物理组件或对象(如刚体)就用这个函数。更改的代码和注释如下。

public class RubyControl2 : MonoBehaviour
{
    //创建一个刚体变量
    Rigidbody2D rigidbody2d;
    //因为要在不同函数中使用这两个变量,所以要声明在最外侧
    float horizontal;
    float vertical;
    // Start is called before the first frame update
    void Start()
    {
        //将脚本中的Rigidbody2D中的属性赋值给rigidbody2d
        rigidbody2d = GetComponent<Rigidbody2D>();
    }

    void Update()
    {
        //利用GetAxis函数,调用用户输入的轴的值
        horizontal = Input.GetAxis("Horizontal");
        vertical = Input.GetAxis("Vertical");      
    }
    private void FixedUpdate()
    {
        //得到脚本中Ruby刚体的位置信息
        Vector2 position = rigidbody2d.position;
        //每一帧,x的位置的加0.1f乘以用户输入移动的量
        position.x += 3f * horizontal * Time.deltaTime;
        position.y += 3f * vertical * Time.deltaTime;
        //将移动的距离返回给Ruby刚体
        rigidbody2d.MovePosition(position);
    }
}

        现在Ruby与物体碰撞已经不造成卡顿了,我们继续来处理一下Ruby与瓦片的碰撞。

添加瓦片地图碰撞

        加入我们要实现Ruby在地板上可以走,但是不能再水上走,我们先来创建一个新的RuleTile2,存放新的水池瓦片,这里介绍一个新的功能,Advanced Rule Override Tile(高级规则覆盖平铺),可以直接照搬已经制作好的瓦片的格式进行修改。

        首先按照下图创建一个RuleTile2。

unity2d 游戏制作 教程 unity制作2d游戏总结_游戏_07

         如我们需要制作和上次的红土地包围地板格式功能一样的瓦片,我们只需要在下图Tile右边的小按钮点击,就会弹出一个Select RuleTile的窗口,在里面选择我们的RuleTile1,就会发现下方已经全部匹配上RuleTile1的规则了,接下来我们就只需要将要更改的图片按照顺序拖进去就行了。

unity2d 游戏制作 教程 unity制作2d游戏总结_游戏引擎_08

         然后把制作好的瓦片放入Tile Palette中,在地图上画一个水池,接下来我们就要制作瓦片的碰撞了,让Ruby不能走进水里。

        我们点击Hierarchy窗口Grid中的Tilemap,在他的inspector窗口中,添加Tilemap Collider 2D。添加过后所有的瓦片都变成了碰撞体,在Scene中体现为一块块绿色的方块。

        将不需要改变为碰撞体的瓦片的Default Collider(默认碰撞器)改为none,这样碰撞效果就不会实现。

unity2d 游戏制作 教程 unity制作2d游戏总结_游戏_09

         更改过后会发现,只有水池上有代表碰撞体的绿色方框了,但是如果地图很大,每个碰撞体方块都要单独渲染,很浪费计算机资源,所以我们要将这些设置为一个碰撞体集合,这样渲染时就少很多工作量。

unity2d 游戏制作 教程 unity制作2d游戏总结_学习_10

         我们在水池瓦片的Inspector中添加Composite Collider (复合对撞机)2D组件,会发现自动添加了Rigidbody 2D组件,因为碰撞需要刚体组件。选中Used By composite,并将BodyType选为Static。

unity2d 游戏制作 教程 unity制作2d游戏总结_游戏_11

         

         这时再看就会发现是大块绿色碰撞体了。