「簡単なパックマン風のゲーム」をUnityで作成する。第2回目です。
はじめに
Part1は下記になります。
Part1ではプレイヤーの移動を作成しました。Part2ではステージ(フィールド)を作成していきます。
作成開始
プレイヤーが動くステージを作成していきます。
ステージの作成
ステージは下記画像を利用していきます。

画像を6枚(16×16のサイズ)に分割して、Unityに取り込みます。

プレイヤーの時と同じように画像の設定をします。PixelsPerUnitは16(プレイヤーの倍)で設定します。

タイルマップでステージを作成
Hierarchyから「2DObject」→「Tilemap」→「Rectangular」を選択します。

TilePaletteにステージの画像を全てドラッグアンドドロップします。

シーンにタイルを貼り、下記のような感じに壁を設置してステージを作成します。

タイルマップでステージを作成するのは下記が参考になります。
プレイヤーとステージの調整
壁の間をプレイヤーが通るように調節していきます。
まずはStageの設定をします。LayerにStageをセットし、TilemapCollider2Dをアタッチします。

次にPlayerの設定です。TagをPlayerにして位置(Position)を変更、「Order in Layer」を変更して手前に表示されるようにします。

更に「CircleCollider2D」をアタッチし、隙間を通るようにRadiusを調整します。0.5がピッタリです。

この状態だと壁との摩擦が発生するので、摩擦をなくしていきます。
Assetsフォルダ内にMaterialsフォルダを作成して、「Create」→「2D」→「PhysicsMaterial2D」を選択します。

Frictionを0(摩擦なし)にします。

StageのMaterialにセットします。

試しに動かすと下記のような感じに。壁方向にキーを入力すると壁にぶつかりプレイヤーが止まるので修正していきます。

Playerのスクリプトを下記のように変更します。
using UnityEngine; public class Player : MonoBehaviour { [SerializeField] private LayerMask stageLayer; private Rigidbody2D rb; private float speed = 8.0f; private Vector2 _direction; private Vector2 _directionReserve; private void Start() { rb = GetComponent<Rigidbody2D>(); _direction = Vector2.right; } private void Update() { if (Input.GetAxisRaw("Horizontal") != 0|| Input.GetAxisRaw("Vertical") != 0) { _directionReserve.x = Input.GetAxisRaw("Horizontal"); _directionReserve.y = Input.GetAxisRaw("Vertical"); } if (_directionReserve != Vector2.zero) { CheckDirection(_directionReserve); } float angle = Mathf.Atan2(_direction.y, _direction.x) * Mathf.Rad2Deg; transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward); } private void FixedUpdate() { Vector2 dist = _direction * speed * Time.fixedDeltaTime; rb.MovePosition(rb.position + dist); } private void CheckDirection(Vector2 direction) { RaycastHit2D hit = Physics2D.BoxCast (transform.position, Vector2.one * 0.5f, 0.0f, direction, 1.0f, stageLayer); if (hit.collider == null) { _direction = direction; _directionReserve = Vector2.zero; } } }
入力した方向を予約状態にして、方向転換できるかチェックをしながら進むように変更しています。プレイヤーから箱形のレイを飛ばして、壁が無い場合は方向転換します。
Layerをセットして、想定したように動けばOKです。
