【Unity】RPGを作るチュートリアルその65 ゲームで使うマップの作成
- 2025.04.13
- RPGチュートリアル
- RPG, Unity, ゲーム開発, チュートリアル

シンプルなRPGをUnityで作るチュートリアルシリーズの65回目です。
第64回ではマップの管理クラスを作成して、エンカウントの動作を確認しました。
今回はゲームで使うマップを作成していきましょう。
制作環境
MacBook Pro 2023 Apple M2 Max
Unity6 (6000.0.30f1) Silicon
作業内容と順序
シンプルなRPGを作る上でどんな作業が必要か、どんな順番で作っていくと良さそうか、別ページで検討しました。基本的にこの流れに沿って進めていきます。
チュートリアルの一覧
このシリーズ全体の一覧は以下のページにまとめています。
前回の内容
前回はマップの管理クラスを作成して、エンカウントの動作を確認しました。
タイルの作成
今回のチュートリアルでは、大きく分けて3種類のマップを作成したいと思います。
- 村
- フィールド
- 洞窟
最初はそれぞれ1マップとして作っていきます。必要なタイルについてはチュートリアル用に作成してあるため、ダウンロードしてインポートできるようにしてあります。それぞれ個別にダウンロードするのも大変なので、zipでまとめたものもあります。(map_tile.zip)
村用タイル
村用マップでは、自宅、村長の家、道具屋を作っていきます。必要なタイルとしては以下のものになります。




フィールド用タイル
フィールド用マップでは村や洞窟のアイコン、山などを配置しましょう。



洞窟用タイル
洞窟用マップでは床、壁を配置していきます。宝箱のタイルも作成してあります。イベントによる制御を入れるため、宝箱はタイルとして配置するのではなく個別のゲームオブジェクトとして配置予定です。




タイルのインポート
必要なタイルをダウンロードしたら、プロジェクトにインポートします。UnityのProjectウィンドウから「Assets/Images/Tiles」のフォルダを開き、ダウンロードしたタイル用画像をインポートします。

インポートした画像を複数選択した状態でインポート設定を行います。タイル用画像に関しては設定のプリセットを作成してあるので、それを適用しましょう。Inspectorウィンドウの右上にあるプリセットボタンをクリックしてウィンドウを開き、「TileImporter」のプリセットをダブルクリックで選択後、Inspectorウィンドウ右下の [Apply] をクリックして適用します。

インポート設定が終わったら、「Tile Palette」のウィンドウを開き、インポートした画像をドラッグ&ドロップします。パレットは既存のものを使い、そこに追加していきます。

タイルの保存先は、モック用のタイルと同じフォルダである「Assets/Tiles」にします。

タイルが追加されると以下のように表示されます。今回はタイル数が少ないのでひとつのパレットで管理していますが、規模が大きい場合はパレットを分けておくと便利です。後から分けるとタイルの参照切れなどのリスクもあるので、先にある程度決めておくと手戻りが少ないかもしれません。

マップの作成
タイルをインポートしたら、マップを作成していきます。マップの構成はテスト用マップのものを使い、タイルの配置を変えていくイメージで作業を進めます。
村のマップの作成
Projectウィンドウから「Assets/Prefabs/Map」のフォルダを開き、テスト用マップのPrefabである「Map_0000_TestMap」を複製します。名前は [Map_0001_Village] にしました。

Inspectorウィンドウでは「Map Id」の値を [1] に、「Map Name」を [村] に変更し、「Encounter Data」に [EncounterData_Village] をアサインします。

作成したPrefabは、Hierarchyウィンドウの「Grid」のゲームオブジェクトの下にインスタンス化しましょう。また、既存のテスト用マップのゲームオブジェクトは削除しました。すでにPrefabにしてあるので、すぐに復元できるので安心です。さらに、タイル配置のしやすさを考え、NPCのゲームオブジェクトについては非表示にしました。NPCはマップ内に配置されるので、こちらも後の回で調整しましょう。

インスタンス化した「Map_0001_Village」のゲームオブジェクトについては、Prefabの編集画面を開いて、タイルを配置していきます。村に関しては壁と木、机を通行禁止タイルに登録予定なので、こちらを使って移動できる範囲を決めていきます。基本方針としては下地に草のタイル、家の範囲は床のタイル、あとはPropsのレイヤーに壁や木などを配置していきます。あとで作る場所移動イベントの位置を調整すればいいので、任意の位置にタイルを配置してください。私は以下のように、左が自宅、上が村長宅、右が道具屋、といった感じで配置してみました。
タイルの範囲外がカメラに映らないように、木のタイルで移動できる範囲を絞り、そこから6マス分くらい多めに下地のタイルを配置しています。

編集後はPrefabを保存します。
フィールドのマップの作成
Projectウィンドウから「Assets/Prefabs/Map」のフォルダにて、村用マップのPrefabである「Map_0001_Village」を複製します。名前は [Map_0002_Field] にしました。

Inspectorウィンドウでは「Map Id」の値を [2] に、「Map Name」を [フィールド] に変更し、「Encounter Data」に [EncounterData_Field] をアサインします。

作成したPrefabは、村のPrefabと同様にHierarchyウィンドウの「Grid」のゲームオブジェクトの下にインスタンス化しましょう。村のPrefabについては編集内容が保存されていることを確認してから削除します。確認方法としては、Inspectorウィンドウから「Overrides」のプルダウンをクリックして、「No Overrides」の表示があれば保存されているPrefabとの差分がない状態になっています。

フィールドについてもタイルを配置していきます。今回は山を通行禁止タイルにして移動できないようにする予定です。ちょっと小さくなっていますが、歩ける領域の左下に村、右上に洞窟を配置しています。フィールドでは村から洞窟への移動を行う想定です。山で囲まれていると魔界塔士Sa・Gaみたいなマップですね。

編集後はPrefabの保存をお忘れなく。
洞窟のマップの作成
Projectウィンドウから「Assets/Prefabs/Map」のフォルダにて、村用マップのPrefabである「Map_0001_Village」を複製します。名前は [Map_0003_Dungeon] にしました。

Inspectorウィンドウでは「Map Id」の値を [3] に、「Map Name」を [ダンジョン] に変更し、「Encounter Data」に [EncounterData_Dungeon] をアサインします。

作成したPrefabは、村やフィールドのPrefabと同様にHierarchyウィンドウの「Grid」のゲームオブジェクトの下にインスタンス化しましょう。フィールドのPrefabもOverrideがないことを確認して削除しておきます。インスタンス化したゲームオブジェクトにタイルを配置していきましょう。左側の蛇の尻尾みたいな部分が出入り口で、右側の蛇の頭みたいな部分がボス部屋です。宝箱はタイルとしてではなく、個別のゲームオブジェクトとして配置する予定なので、ここではまだ配置しません。

こちらも編集後はPrefabの保存をお忘れなく。
通行禁止タイルの設定
山や木など、通行できないタイルを登録していきます。Projectウィンドウから「Assets/Data」のフォルダを開き、「NoEntryTileData」のタイルを選択します。Inspectorウィンドウから通行できないタイルを追加していきましょう。対象は以下の通りです。
- ダンジョンの壁
- フィールドの山
- 村のテーブル
- 村の木
- 村の壁
それぞれ対応するタイルをリストに追加します。

PrefabをAddressables Groupに登録
作成したマップをロードできるように、Addressables Groupに登録します。村、フィールド、洞窟のマップのPrefabをドラッグ&ドロップして「Map」のGroupに登録しましょう。コンテキストメニューから「Simplify Addressable Names」を選択して名前をシンプルにしたあと、「Labels」のプルダウンで「Map」を選択します。

TilemapManagerへのマップのセット
動的にマップを切り替えるため、キャラクターの位置を参照するためのTilemapが変わっていきます。そのため、「MapManager」から「TilemapManager」に対して、現在表示中のマップに対応するTilemapをセットする処理を追加します。自身のマップに対応するTilemapについては、Inspectorウィンドウから設定できるようにしておきます。テスト用のマップを実装するときに気づけば手間を減らせたのでは……?(1敗)
また、「CharacterMover」でも現在のTilemapを参照して位置を取得しているため、それを新しいマップ上の位置に切り替える処理も行います。
TilemapManagerの変更
「TilemapManager」では、新しいマップのTilemapをセットできるメソッドを追加します。また、キャラクターが移動先の位置を予約するためのリストもあるので、マップを切り替えたタイミングでこちらをリセットするようにします。
既存のReservePosition()のメソッドの下に2つのメソッドを追加しました。SetTilemaps()のメソッドは新しいマップのTilemapをセットするためのメソッドで、下地、装飾品、オーバーレイの各レイヤーのTilemapを渡して、フィールドにセットするようにしています。
ResetPositions()のメソッドはキャラクターが予約した移動位置をリセットしています。
MapControllerの変更
MapControllerで各Tilemapの参照用フィールドを追加します。また、引数のTilemapManagerにその参照を渡す処理も入れておきます。
CharacterMoverの変更
「CharacterMover」ではTilemap上の位置を取得する処理について外部から呼び出せるようにしたいと思います。既存のResumeMoving()の下にResetPosition()のメソッドを追加しました。中で呼んでいるGetCurrentPositionOnTilemap()はStart()の中で呼んでいるものです。
CharacterMoverManagerの変更
「CharacterMoverManager」では「CharacterMover」で追加したResetPosition()を呼び出すためのメソッドのResetPositions()を追加しました。既存のResumeCharacterMover()の下に入れています。
MapManagerの変更
マップ表示時に上で追加した処理を呼ぶようにします。
フィールドとして、「TilemapManager」と「CharacterMoverManager」への参照を保持できるようにします。こちらはInspectorウィンドウからアサインするようにしましょう。
既存のShowMap()のメソッドにて、表示した後の処理としてTilemapの設定、Tilemap上の予約位置のリセット、キャラクターが認識しているタイル上の位置をリセットします。
参照のアサイン
スクリプトを保存したら、追加したフィールドの参照をアサインします。
「MapManager」では「TilemapManager」と「CharacterMoverManager」への参照をアサインします。

また、マップ用のPrefabについて、それぞれ対応するTilemapのレイヤーをアサインします。Prefabが4つあって大変ですが、それぞれアサインしていきます。

動作確認
スクリプトをアタッチしたら、ゲームを開始して動作を確認します。と、その前に、「MapManager」にて「Game Start Map Id」の値を [1] にしておきます。これで村からスタートするようになります。

マップ内を移動できること、侵入禁止タイルに設定したタイルの上には移動できないことを確認します。フィールドと洞窟に関してはエンカウントする可能性があるので、確認中はエンカウントしないように定義データのチェックを外しておくと楽ちんです。マップを切り替える際には「MapManager」の「Debug Target Map Id」を変更してチェックを入れると切り替えができます。
また、移動速度を上げるならゲームの実行中に「PlayerMover」の「Move Time」の値を減らすと速く移動できます。

もしタイルが配置されていない領域が表示される場合は、Prefabにてタイルをさらに広く配置しておくと良いかと思います。私は洞窟のタイルを広げました。
ここまで確認できたら今回は完了です。
今回のブランチ
まとめ
今回はゲームで使うマップを作成しました。マップを作って動かせる状態になるとRPGっぽさが増してきますね。
次回はメニュー画面の機能を作るにあたって、方針を決めてUI作成に着手します。
ゲーム開発の攻略チャートを作りました!
-
前の記事
【Unity】RPGを作るチュートリアルその64 マップを管理するクラスを作成 2025.04.09
-
次の記事
記事がありません
コメントを書く