知りたい方がいらっしゃったので書いてみました。
インスペクタから設定できると、データベース不要で簡単に複数マップを作成・管理できるところが良いところだと思います。
設定ファイルの作成
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を作成せずに楽に作れるよう設計しました。
もし「こうした方がいいよ」というのがあれば教えてください。