見出し画像

UnityのTilemap 徹底まとめ⑥ | Isometric Tilemapに当たり判定を設定する

前回は、Isometric Tilemapの重なり順について確認しました。
Isometric Tilemapでは、木や建物、プレイヤーなどを配置すると、前後関係がとても大切になります。

前回、Playerを上下左右に移動させて、木の前にいるときは手前に表示され、木の後ろに回り込むと木の後ろに隠れる、という動きを確認しました。

今回も前回の続きとして、同じPlayerを使って進めていきますが、動きを制限しておらず、木や壁、建物を置いても、Playerはそのまますり抜けてしまいます。

Isometricのマップとして自然に見せるためには、

・地面の上は歩ける
・木や壁にはぶつかる
・建物の中には入れない
・通れる場所と通れない場所を分ける

といった設定が必要になります。
そこで今回は、Isometric Tilemapに当たり判定を設定し、Playerが障害物をすり抜けないようにする方法を確認していきます。



今回作る内容

今回は、前回作成したIsometric Tilemapに当たり判定を追加します。

前回の時点では、Playerは次のようなコードで移動できる状態になっています。

using UnityEngine;

public class MyChar : MonoBehaviour 
{
    public float speed = 2; // 移動速度
    
    void Update()
    {   
        float stepx = Input.GetAxis("Horizontal") * speed * Time.deltaTime;  // 水平移動量
        float stepy = Input.GetAxis("Vertical") * speed * Time.deltaTime;    // 垂直移動量

        transform.Translate(stepx, stepy, 0); // 移動
    }
}

このコードでPlayerを動かすことはできます。
ただしこの移動方法は、Transformコンポーネントの Position(座標)の値を直接置き換えて移動させているので、木や壁にぶつかっても止まらず、そのまますり抜けてしまいます。

今回は、次のような状態を作ります。

・Playerは地面の上を移動できる
・木や壁などのObject Tilemapにはぶつかる
・障害物をすり抜けない
・Tilemapごとに当たり判定を管理する


Tilemapの状態を確認

前回までに、Tilemapは次のように分けていました。

・Ground Tilemap
地面、床、道などを配置するTilemap

・Object Tilemap
木、建物、壁、柱などを配置するTilemap

Ground Tilemap は、Playerが歩く場所です。
Object Tilemap は、Playerがぶつかるものを置く場所です。

今回のポイントは、
Groundには当たり判定をつけず、Objectに当たり判定をつける
という考え方です。


Colliderの設定

Unityの2Dで当たり判定を実現するには、主にCollider 2Dというコンポーネントを使用します。

たとえば、PlayerにCollider 2Dを設定し、木や壁にもCollider 2Dを設定すると、Playerが木や壁にぶつかったことを判定できるようになります。
ただし、Colliderをつけるだけでは、必ずしも物理的に止まるわけではありません。

Player側には、Rigidbody2Dも必要になります。
簡単に言うと、次のような役割です。

・Collider 2D → ぶつかる形を決める
・Rigidbody2D → 物理的な動きを扱う
・Tilemap Collider 2D → Tilemapに配置したタイルに当たり判定をつける

【画像:Collider 2DとRigidbody2Dの役割図】


PlayerにCollider

まず、Playerに当たり判定を設定します。
Playerを選択し、InspectorからAdd Componentをクリックします。
今回は、Playerの形に合わせてBox Collider 2Dを追加します。

Colliderの大きさは、Player画像全体に合わせる必要はありません。
足元付近を中心に、少し小さめに設定すると自然に動きやすくなります。
キャラクターの頭や体全体に大きく当たり判定をつけると、見た目より早く壁にぶつかってしまうことがあります。
「EditCollider」を押して、当たり判定の大きさを調整します。


PlayerにRigidbody2D

次に、PlayerにRigidbody2Dを追加します。
Playerを選択した状態で、Add ComponentからRigidbody2Dを追加。

Rigidbody2Dを追加すると、重力の影響を受ける場合があります。
今回は重力の影響を受けなくても良いので、Gravity Scaleを0にします。

Freeze Rotation Zにチェックを入れておくと、ぶつかったときにPlayerが回転してしまうのを防げます。


Object TilemapにTilemap Collider 2Dを設定する

次に、木や壁を配置しているObject Tilemapに当たり判定を設定します。

Object Tilemapを選択します。
InspectorからAdd Componentをクリックし、Tilemap Collider 2Dを追加します。
これで、Object Tilemapに配置されているタイルに当たり判定がつきます。

Tilemap Collider 2Dを追加すると、配置されているタイルの形に合わせてColliderが作成されます。

これにより、Playerが木や壁にぶつかったときに、すり抜けにくくなります。


Composite Collider 2D

Tilemap Collider 2Dを追加すると、Tilemap上のタイル1枚1枚に当たり判定が作られます。
小さなマップであれば、そのままでも問題ありません。
ただし、タイルの数が多くなると当たり判定の数も多くなり、マップが大きくなると処理が重くなることがあります。
また、タイル1枚ごとにColliderが分かれているため、移動中に引っかかるように感じる場合もあります。

このようなときに使うのが、Composite Collider 2Dです。
Composite Collider 2Dを使うと、Tilemap Collider 2Dの当たり判定をまとめることができます。

事前に Tilemap Collider 2D の Composite Operation を Marge にしておきます。
UnityEditorのバージョンによっては Used By Compositeにチェックを入れることでこの処理と同じ効果が得られます。

続いて、Object Tilemapを選択した状態で、Add ComponentからComposite Collider 2Dを追加します。

その際、Rigidbody2Dも追加されます。
Rigidbody2Dは動かない障害物として使うため、Body TypeをStatic にしておきます。

これにより、タイルごとの細かい境目が整理され、当たり判定を扱いやすくなります。


Playerの移動方法の変更

冒頭で説明した通り、前回作成した簡易的なPlayerの動きでは、transformコンポーネントの座標を使って移動をさせています。
その場合、当たり判定があっても強制的に移動が優先される場合があります。
そこで作成済みのスクリプトファイル MyChar を今回は Rigidbody2D を使った移動に置き換えます。

public class MyChar : MonoBehaviour
{
    public float speed = 2f; // 移動速度
    Rigidbody2D rb;          // Rigidbody2Dを入れる変数
    Vector2 moveInput;       // 入力方向を入れる変数

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();   // Rigidbody2Dを取得
    }
    
    void Update()
    {
        float stepX = Input.GetAxisRaw("Horizontal"); // 左右の入力を取得
        float StepY = Input.GetAxisRaw("Vertical");   // 上下の入力を取得
        // 入力方向を正規化してmoveInputに代入
        moveInput = new Vector2(stepX, StepY).normalized;
    }

    void FixedUpdate()
    {
        rb.linearVelocity = moveInput * speed;
    }
}

実際に動かして確認する

設定ができたら、ゲームを再生して確認します。
Playerを動かして、Object Tilemapに配置した木や壁に向かって移動してみます。
正しく設定できていれば、Playerは木や壁をすり抜けず、ぶつかって止まります。


今回のまとめ

今回は、Isometric Tilemapに当たり判定を設定し、Playerが木や壁をすり抜けないようにする方法を確認しました。

ポイントは次の通りです。

・前回のPlayer移動を使って、今回は当たり判定を追加する
・PlayerにはCollider 2Dを設定する
・PlayerにはRigidbody2Dを設定する
・Gravity Scaleは0にする
・Freeze Rotation Zで回転を防ぐ
・Object TilemapにはTilemap Collider 2Dを設定する
・必要に応じてComposite Collider 2Dで当たり判定をまとめる
・Object TilemapのRigidbody2DはStaticにする
・Ground Tilemapには基本的に当たり判定をつけない
・地面は歩ける場所、Objectはぶつかる場所として分ける

Isometricマップでは、見た目の前後関係だけでなく、実際にどこを歩けるのか、どこで止まるのかも大切です。

まずは、Ground TilemapとObject Tilemapを分けて、Object側に当たり判定をつけるところから始めると分かりやすいです。

次回は、Tilemapに高さや段差を持たせる方法を説明します。


こちらはUnity初心者向けの記事をテーマ別にまとめています。
▼ Unity初心者向け記事まとめはこちら


▼ Unity初心者向け記事まとめはこちら


こちらのマガジン「ミニゲーム作成講座 全8回セット」でもシーンの切り替えなどを活用して、初心者でも知識ゼロから作れるミニゲーム作成講座を紹介しています。

さらにステップアップの「スマホで遊ぶジャンプゲーム 8回セット」のマガジンもぜひご活用ください。


ファイブボックスでは、スクラッチやUnityの個別指導のオンラインレッスンを行っています。
ご興味のある方は当サイト、オンラインレッスンから、無料体験授業へお問い合わせ下さい。

いいなと思ったら応援しよう!

ファイブボックス よろしければ応援お願いします! いただいたチップはクリエイターとしての活動費に使わせていただきます!