【Unity】2Dタイルマップ⑩ Isometricなマップで建物の上を通る・下をくぐる【後編】
Unity 2020.2.1f1 Personal(2021年3月)
前回の続きです!
前編ではTilemapの配置とPlayerの作成を行ました。
後編ではCollider用Tilemapの作成とプレイヤーの位置によって有効なColliderを切り替える方法を解説します。
この記事はUnity 公式のIsometric 2DTilemapプロジェクトを一部参考にしています。
TilePaletteの作成(ColliderPalette)
まずはColliderTilemap用のパレットを作成します。
ColliderPaletteという名前でTilePaletteを作成して下さい。
ColliderPalette作成
続いてColliderとなるSpriteをパレットに登録していきます。
以下の画像をUnityにアップして下さい。
collider1.png
collider2.png
collider3.png
collider4.png
collider5.png
collider6.png
各Spriteの設定は以下の通りです。
またSprite EditorのCustom Physics Shapeにて各Spriteの形通りに囲って下さい。
collider1.pngの例
各Spriteの設定が完了したらColliderPaletteにドラッグ&ドロップしTileを登録していきます。
Collider用Tileを登録
Tilemapを作成する(Collider用Tile)
パレットの設定が完了したので続いてTileを配置していきます。
今回は1階用・階段用・2階用のTilemapを作成します。
まずは1階用Tilemapです。
HierarchyからCreate > 2D Object > Tilemap > IsometricでTilemapを作成して下さい。
名前は「Collider1f」とします。
Tilemap作成
作成したTilemapのTilemapRendererのModeをIndividualに、
またColliderを確認しやすいようにSorting Layerに「ColliderDebug」を作成して設定します。
またColliderを確認しやすいように色を透けたピンクにします。
ProjectビューにてCreate > MaterialでMaterialを新規作成し、名前を「ColliderTilemap」にします。
作成したMaterialのInspectorから、ShaderをSprite/Defaultに、Tintをピンクにして透明度を60%程度にします。
作成したMaterialをCollider1fのTilemapRendererのMaterialに設定します。
Materialを設定
あとはCollider1fオブジェクトにTilemapCollider2DとCompositeCollider2Dを取り付けます。
TilemapCollider2DのUsed byCompositeをtrueに、
自動的に取り付けられるRigidbody2DのBody TypeをKinematicに変更します。
TilemapCollider2D, Rigidbody2D, CompositeCollider2Dの設定
Tileを配置する(Collider用Tile)
ようやくTilemapの準備が完了しました。
それではTileを配置していきます。
1階のColliderを配置
フィールドの外に出ないように囲ったのと、階段の後ろ側をブロックしました。
同じ要領で階段用のTilemapを作成します。
基本的にはCollider1fと同じです。
・ColliderStairという名前でTIlemap作成
・ModeをIndividualに変更
・MaterialにColliderTilemapを設定
・Sorting LayerをColliderDebugに設定
・TilemapCollider2Dを取り付けUsed by Compositeをtrue
・Composite Collider2Dを取り付ける
・Rigidbody2DのBody TypeをKinematicに設定
階段のColliderを配置
同じようにCollider2fという名前の2階用Tilemapを作成し、Tileを配置していきます。
2階のColliderを配置
以上でCollider用のTilemapの作成は完了です。
Collider用Tilemapを3つ作成
プレイヤーの位置によって有効なColliderを切り替える
Collider用TIlemapの作成まで完了しました。
最後にプレイヤーの位置によって有効なColliderを切り替える機能を実装します。(1階にいる時は1階のColliderを、2階にいる時は2階のColliderを有効にする)
まずはMapController.csを作成します。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class MapController : MonoBehaviour { public static MapController instance; [SerializeField] List<GameObject> floorList; private void Awake() { if (instance == null) { instance = this; } else { Destroy(this.gameObject); } } private void Start() { SetCurrentFloor(0); } public void SetCurrentFloor(int floor) { for (int i = 0; i < floorList.Count; i++) { floorList[i].SetActive(i == floor); } } }
MapController.cs
こちらのScriptをControllerオブジェクトに取り付けて下さい。
またInspectorからFloorListを3つ用意し、各Collider用のTilemapを登録します。
Collider1f, ColliderStair, Collider2fの順番で登録する。
SetCurrentFloorメソッドを実行すると
引数で設定したCollider用Tilemapが有効になりそれ以外のCollider用Tilemapが無効になります。
続いて階を切り替えるポイントとなるFloorChangePointオブジェクトを作成していきます。
空オブジェクトを作成し名前を「FloorChangePoint」に変更します。
作成したFloorChangePointオブジェクトはCollider1fオブジェクトの子オブジェクトにします。
InspectorからPolygonCollider2Dコンポーネントを取り付け、
PolygonCollider2DのEdit Colliderから下の画像のように階段の入り口にColliderを形作ります。
PolygonCollider2DのIsTriggerはtrueにしておきます。
最後にFloorChangePoint.csを作成しFloorChangePointオブジェクトに取り付けます。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class FloorChangePoint : MonoBehaviour { [SerializeField] int floorNum; private void OnTriggerExit2D(Collider2D collision) { if (collision.transform.tag == "Player") { MapController.instance.SetCurrentFloor(floorNum); switch (floorNum) { case 0: collision.transform.GetComponent<Player>().SetZPos(2f); break; case 1: case 2: collision.transform.GetComponent<Player>().SetZPos(8f); break; } } } }
FloorChangePoint.cs
OnTriggerExit2Dが実行されるタイミングは先ほど作成したColliderをPlayerオブジェクトが外に出たタイミングです。
先ほどのMapControllerのSetCurrentFloorメソッドが実行されます。
引数のfloorNumはFloorChangePointオブジェクトのInspectorから設定できます。
Collider1fを非表示にしてColliderStairを表示したい場合は、floorNumを1に設定する、といった感じです。
switch文ではPlayerのposition.zを変更しています。
というわけでPlayer.csにSetZPosメソッドと追加していきます。
Player.csにSetZPosメソッドを追加
それではPlayer.csにSetZPosメソッドを追加修正していきます。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Player : MonoBehaviour { private readonly float speed = 0.03f; 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); } // ***** 追加 ***** public void SetZPos(float zPos) { transform.position = new Vector3(transform.position.x, transform.position.y, zPos); } // ***** 追加終了 ***** }
Player.cs
SetZPosメソッドは単純にPlayerのzPosを更新するだけのメソッドです。
FloorChangePointを複数作成する
ここまででPlayerが階段を通過しようとするとCollider1fが無効になり、ColliderStairが有効になるようになりました。
同じように階段から2階へ上がるポイントにFloorChangePointオブジェクトを置きます。
FloorChangePointをPrefab化し、ColliderStairオブジェクトの子オブジェクトにします。
ColliderStairを非表示にしCollider2fを表示させたいので、
FloorChangePoint.csのfloorNumを2にします。
位置としては階段と2階の間です。
階段と2階の間にCollider配置
続いて2階から階段へ移動するFloorChangePointオブジェクトを作成します。
Collider2fオブジェクトの子オブジェクトとしてFloorChangePointオブジェクトを作成し、FloorChangePoint.csのfloorNumを1にします。
位置としては階段と2階の間ですが、先ほど作成した2階に切り替えるFloorChangePointオブジェクトより階段寄りに配置します。
階段と2階の間にCollider配置
最後に階段から1階へ移動するFloorChangePointオブジェクトを作成します。
ColliderStairオブジェクトの子オブジェクトに作成し、floorNumを0にします。
最初に作成したFloorChangePointオブジェクトより1階寄りに配置します。
1階と階段の間にCollider配置
以上で左側の階段のFloorChangePointの作成が完了しました。
右側の階段も同様の手順でFloorChangePointを配置したら作業完了です。
結果
それでは結果を確認していきます。
まずは建物の下をくぐってみます。
有効になっているColliderは1階のみなので、
当然建物の下をくぐることができます。
続いて建物の上を通ります。
1階、階段、2階とプレイヤーの位置によって有効なColliderを切替え、
無事建物の上を通過することができました。
オマケ:HideTilemapRendererスクリプト
ゲーム開始時にTilemapColliderの色を消すHideTilemapRenderer.csを最後に掲載します。
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Tilemaps; public class HideTilemapRenderer : MonoBehaviour { void Start() { GetComponent<TilemapRenderer>().enabled = false; } }
HideTilemapRenderer.cs
TilemapRendererのenabledをfalseにして色だけ消しています。(Colliderは残っています。)
using UnityEngine.Tilemaps;
の記述をしないとTilemapRendererを使えないのでご注意下さい。
こちらのScriptをCollider1f, ColliderStair, Collider2fオブジェクトにつけることでゲーム開始時にColliderの色を隠すことができます。
というわけで今回は以上です。
ありがとうございました〜。