Unity(C#)初心者・入門者向けチュートリアル ひよこのたまご

AndroidやiOS向けアプリを簡単に作れるゲーム開発環境Unity(ユニティ)の使い方を、チュートリアル方式で一緒に学びましょう!

【Unity】2Dタイルマップ13 Playerが扉の前に移動したら扉を開く

f:id:hiyotama:20210322201410p:plain
Unity 2020.2.1f1 Personal(2021年3月)
前回の続きです!
今回はIsometricな2Dタイルマップにて、
扉のTileの前に来た時にドアTileを消して建物の中に入る機能を実装していきます。

TilePaletteにTileを登録する

まずはTilePaletteにTileを登録します。
以下のSpriteをUnityにアップして下さい。
f:id:hiyotama:20210323003333p:plain
stone_block.png
f:id:hiyotama:20210323003352p:plain
stone_wall.png
f:id:hiyotama:20210323003359p:plain
stone_wall_door_open.png
f:id:hiyotama:20210323003403p:plain
door_close.png

各SpriteはPixel per Unitを32Filter ModeをPoint(no filter)に設定します。
またstone_wall、stone_wall_door_open、door_closeにColliderを設定します。
Sprite EditorのCustom Physics Shapeから設定できます。

f:id:hiyotama:20210323003911p:plain
stone_wallのCustom Physics Shape

f:id:hiyotama:20210323004026p:plain
stone_wall_door_openのCustom Physics Shape

f:id:hiyotama:20210323004136p:plain
door_closeのCustom Physics Shape

これらの設定が完了したら4つのSpriteをTilePaletteに登録します。
TilePaletteの作成についてはこちらの過去記事をご参照ください。

hiyotama.hatenablog.com

今回は名前を「IsometricPalette」、Tileに高さを与えるのでGridをIsometric Z as Yで新規作成して下さい。

f:id:hiyotama:20210323004934p:plain
TilePaletteに各Spriteを登録

Tilemapの作成とTileの配置

続いて登録したTileをSceneに配置していきます。
まずはTIlemapオブジェクトを作成します。
Hierarchyから2D Object > Tilemap > Isometric Z as Yで作成します。

f:id:hiyotama:20210323014500p:plain

作成したTilemapオブジェクトのTilemapRenderer > ModeをIndividualに変更します。
またTilemap Collider2Dをつけておきます。

f:id:hiyotama:20210323014702p:plain

今回選択したIsometric Z as YはTileのposition.zの値によって高さを表現することができます。
Isometric Z as Yを使う時はカメラ設定のTransparency Sort Modeを変更する必要があります。
高さの解説とTransparency Sort Modeの設定はこちらの記事をご参照下さい。
hiyotama.hatenablog.com

それではTileを配置していきます。
まずはZ Position:0から配置します。

f:id:hiyotama:20210323015115p:plain
TilePaletteのZ Positionを0に設定

f:id:hiyotama:20210323015208p:plain
Tileを配置

stone_wall_door_openタイルとstone_wallタイルを配置しました。
この2つの間にdoor_closeタイルを配置します。

f:id:hiyotama:20210323015329p:plain
door_closeを間に配置

door_closeタイルが消えた時にstone_wall_door_openのドア部分が見える仕掛けです。

続いてZ Position: 4のTileを配置していきます。

f:id:hiyotama:20210323020331p:plain
Z Positionを4に設定

f:id:hiyotama:20210323020738p:plain
Tileを配置

stone_blockタイルを3つ置いてTileの配置は完了です。

Playerの作成

続いてPlayerを作成します。
hiyotama.hatenablog.com
こちらの過去記事を参照してPlayerオブジェクトとControllerオブジェクトを作成して下さい。
Inspectorのみこちらにも掲載しておきます。

f:id:hiyotama:20210323022059p:plain
PlayerオブジェクトにはPlayer.cs・CircleCollider2D・Rigidbody2Dを取り付ける

f:id:hiyotama:20210323022813p:plain
ControllerオブジェクトにはPlayerController.csをつけPlayerとCameraを設定する

以上でプレイヤーを動かすことができるようになりました。

Playerがドアの前に来た時にドアを開く

最後にPlayerがドアの前に来た時にドアを開く処理を実装していきます。
先ほど作成したControllerオブジェクトにTilemapController.csを取り付けます。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Tilemaps;


public class TilemapController : MonoBehaviour
{
    public static TilemapController instance;
    [SerializeField] Tilemap defaultTilemap;
    private Vector3Int beforePlayerCellPos;

    private void Awake()
    {
        if (instance == null)
            instance = this;
        else
            Destroy(this.gameObject);
    }


    public void CheckCloseDoor(Vector3 playerPos)
    {
        Vector3Int playerCellPos = defaultTilemap.WorldToCell(playerPos);
        if (beforePlayerCellPos != playerCellPos)
        {
            OpenDoor(playerCellPos - Vector3Int.up);
            OpenDoor(playerCellPos - Vector3Int.down);
            OpenDoor(playerCellPos - Vector3Int.right);
            OpenDoor(playerCellPos - Vector3Int.left);

            beforePlayerCellPos = playerCellPos;
        }
    }


    private void OpenDoor(Vector3Int cellPos)
    {
        var tile = defaultTilemap.GetTile(cellPos);
        if (tile && tile.name == "door_close")
        {
            defaultTilemap.SetTile(cellPos, null);
        }
    }
}

TilemapController.cs

CheckCloseDoorメソッドにPlayerの位置情報を送り、そこからPlayerが現在いるTileのCell位置を割り出します。
現在Cell位置が前フレームのCell位置と違う場合、Playerの前後左右のCell位置を引数にOpenDoorメソッドを呼び出します。
OpenDoorメソッドではGetTileでタイルを取得し、名前が「door_close」だった場合のみタイルを削除しています。

TilemapController.csのdefaultTilemapに今回作成したTilemapを設定します。

f:id:hiyotama:20210323025614p:plain

最後にPlayer.csからTilemapController.csのCheckCloseDoorメソッドを呼び出す記述を追加します。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player : MonoBehaviour
{
    private readonly float speed = 0.03f;


    private void Update()
    {
        TilemapController.instance.CheckCloseDoor(transform.position);
    }


    public void MoveUp()
    {
        transform.position = new Vector3(transform.position.x + speed, transform.position.y + (speed / 2f), transform.position.z);
    }


    public void MoveDown()
    {
        transform.position = new Vector3(transform.position.x - speed, transform.position.y - (speed / 2f), transform.position.z);
    }


    public void MoveLeft()
    {
        transform.position = new Vector3(transform.position.x - speed, transform.position.y + (speed / 2f), transform.position.z);
    }


    public void MoveRight()
    {
        transform.position = new Vector3(transform.position.x + speed, transform.position.y - (speed / 2f), transform.position.z);
    }
}

Player.cs

UpdateメソッドにてTilemapControllerのCheckCloseDoorメソッドを毎フレーム呼び出しチェックしています。

** 結果

f:id:hiyotama:20210323030142g:plain

Playerがドア手前のTileの上に乗った時にドアのTileが削除されドアが開きます。

今回は以上となります。
ありがとうございました〜。