知りたい方がいらっしゃったので書いてみました。
インスペクタから設定できると、データベース不要で簡単に複数マップを作成・管理できるところが良いところだと思います。
設定ファイルの作成
MapSetting.csとして、以下のファイルを作成します。
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// -----------------------------------------//
// マップ本体
// -----------------------------------------//
[Serializable]
public class MapData
{
// -------------------------------------------//
// 基礎
// -------------------------------------------//
[SerializeField] string id = ""; // マップID:同一のものは作らないこと
public string Id{ get{ return id; } }
[SerializeField] string name = "マップ名";
public string Name{ get{ return name; } }
[SerializeField] Sprite imageBackground; // 背景画像
public Sprite ImageBackground{ get{ return imageBackground; } }
[SerializeField] int pxWidth = 100; // マップの大きさ(横)
public int PxWidth{ get{ return pxWidth; } }
[SerializeField] int pxHeight = 200; // マップの大きさ(縦)
public int PxHeight{ get{ return pxHeight; } }
// -------------------------------------------//
// スタート・ゴール・障害物関係
// -------------------------------------------//
// スタート位置
[SerializeField] MapPositionData posStart;
public MapPositionData PosStart{ get{ return posStart; } }
// ゴール位置
[SerializeField] MapPositionData posGoal;
public MapPositionData PosGoal{ get{ return posGoal; } }
// 障害物位置(障害物が1種類なら)
[SerializeField] List<MapPositionData> listPosHurdle;
public List<MapPositionData> ListPosHurdle{ get{ return listPosHurdle; } }
// -------------------------------------------//
// メソッド
// -------------------------------------------//
}
// 位置データ(2D)
[Serializable]
public class MapPositionData
{
[SerializeField] int posX = 0; // X座標
public int PosX{ get{ return posX; } }
[SerializeField] int posY = 0; // Y座標
public int PosY{ get{ return posY; } }
}
// -----------------------------------------//
// 設定用ファイル
// -----------------------------------------//
[CreateAssetMenu()]
[Serializable]
public class MapSetting : ScriptableObject
{
[SerializeField] List<MapData> listData;
// -----------------------------------------//
// メソッド
// -----------------------------------------//
public List<MapData> GetData()
{
return listData;
}
}
// -----------------------------------------//
Scriptable Objectの作成
プロジェクト画面から、右クリック > 作成 > MapSettingで作成します。
Scriptable Objectの調整
Scriptable Objectを選択すると、以下のように設定ができるようになります。
マップを増やすのは+/-で調整可能です。
マップデータ呼び出し用ファイルの作成
マップデータを呼び出す例となるファイルを作成します。
実際に使う場合はインスペクタから、mapSettingにMapSettingファイル(上記で設定したもの)や各種GameObjectをアタッチしてください。
唐突にオブジェクトプールやPrefabという概念が出てきます。そちらは自分で調べるかChatGPTに聞いてみるとよいでしょう。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MapRead : MonoBehaviour
{
// マップデータ
[SerializeField] MapSetting mapSetting;
List<MapData> listMapData;
// オブジェクト(各々アタッチが必要。これらのObjectは開始時・マップ変更時は非アクティブに設定。)
[SerializeField] GameObject objPlayer; // キャラクター
[SerializeField] GameObject objGoal; // ゴール
[SerializeField] List<GameObject> listObjHurdle; // 障害物(オブジェクトプールのように使用)
[SerializeField] GameObject prfHurdle; // 障害物のPrefabをアタッチ(新規にGameObjectを生成するために使用)
// ロード
void Awake()
{
listMapData = mapSetting.GetData();
}
// 初期設定
void Start()
{
ReadMapData();
}
// マップデータ読み込み
void ReadMapData()
{
MapData mapData = listMapData.Find(x => x.Id == "マップID");
// マップの大きさ設定
// SetMapSize(mapData.PxWidth, mapData.PxHeight); // 同様に設定してみてください
// スタート・ゴール位置の設定
SetMapStart(mapData.PosStart);
SetMapGoal(mapData.PosGoal);
// 障害物を設置
// SetMapHurdle(mapData.ListPosHurdle); // スタート・ゴールを設定できたら、コメントアウトを外して試してみてください
}
// 開始位置設定
void SetMapStart(MapPositionData mapPos)
{
objPlayer.transform.position = new Vector3(mapPos.PosX, mapPos.PosY, 0f);
// 表示ON
objPlayer.SetActive(true);
}
// ゴール位置設定
void SetMapGoal(MapPositionData mapPos)
{
objGoal.transform.position = new Vector3(mapPos.PosX, mapPos.PosY, 0f);
// 表示ON
objGoal.SetActive(true);
}
// 障害物設定
void SetMapHurdle(List<MapPositionData> listMapPos)
{
// 現状のObjを全て非表示にする
foreach(GameObject objHurdle in listObjHurdle) objHurdle.SetActive(false);
// 表示するオブジェクト・位置を設定
for(int i=0; i<listMapPos.Count; i++)
{
// 一時Obj
GameObject objTemp = null;
// listObjHurdleの個数を把握
if(listObjHurdle.Count <= i) // 不足する場合
{
objTemp = Instantiate(prfHurdle); // prfHurdleを元にオブジェクトを新規生成
objTemp.SetActive(false); // とりあえず非表示にしておく
listObjHurdle.Add(objTemp); // オブジェクトプールリストに追加
}
else // 充足している場合
{
objTemp = listObjHurdle[i];
}
// 配置・表示
MapPositionData mapPos = listMapPos[i];
objTemp.transform.position = new Vector3(mapPos.PosX, mapPos.PosY, 0f);
objTemp.SetActive(true);
}
}
}
コメント
マップを複数に増やすには、データ作成→管理用UI作成→マップ作成→…と、非常に面倒だったので、管理用UIを作成せずに楽に作れるよう設計しました。
もし「こうした方がいいよ」というのがあれば教えてください。

