💨
共通マスタ ScriptableObject
共通パラメータ管理、初期値の宣言にGameObject使うと大変になる
RPGで敵モンスターをGameObjectごとにHP,MPもたせるときに、MaxHP, MaxMPはReadOnlyで良い上にGameObjectにいちいち持たせていたらモンスターが1種1000体スポーンさせた時でも1000体分のパラメータをバラバラに持たせることになる。
ScriptableObject で共通の種ごとにパラメータ管理などをシンプルに行える。
ScriptableObject 概要
- Object継承クラスであり、GameObjectではないのでエディタ内配置はできない
- MonoBehaviourにあるUpdateメソッドは使えない
EnemyProfile.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// MyScriptable/Create EnemyData のメニュー作成
[CreateAssetMenu(menuName = "MyScriptable/Create EnemyData")]
[System.Serializable]
public class EnemyProfile : ScriptableObject {
public string enemyName;
public int defaultHp;
public int defaultMp;
public static LoadJSON()
{
Debug.Log("LoadJSON");
// ScriptableObjectアセットのファイルパス
var enemyProfile = AssetDatabase.LoadAssetAtPath<EnemyProfile>("");
// JSONファイルのパス
TextAsset localJsonFile = AssetDatabase.LoadAssetAtPath<TextAsset>("");
try {
JsonUtility.FromJsonOverwrite(localJsonFile.text, enemyProfile);
AssetDatabase.SaveAssets();
} catch (Exception e) {
//例外を処理する場合
}
return enemyProfile;
}
public static SaveJSON()
{
Debug.Log("SaveJSON");
// ScriptableObjectアセットのファイルパス
string json = JsonUtility.ToJson (AssetDatabase.LoadAssetAtPath<TestScriptableObject>(""));
try {
// 書き出すファイルのパス
using (StreamWriter writer = new StreamWriter(""))
{
writer.Write(json.ToString());
}
//import
AssetDatabase.ImportAsset(jsonPath);
} catch (Exception e) {
//例外を処理する場合
}
return enemyProfile;
}
public string ToJSON()
{
// floatはToJsonで誤差が生じる
return JsonUtility.ToJson(this);
}
}
Enemy.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Enemy : MonoBehaviour {
[SerializeField] private int iHP;
[SerializeField] private int iMP;
// カスタムクラスのフィールド
[SerializeField] private EnemyProfile enemyProfile;
void Start(){
outputParam;
}
void Update(){
}
void outputParam(){
iHP = enemyProfile.defaultHP;
iMP = enemyProfile.defaultMP;
Debug.Log("HP / MP : " + iHP + " , " + iMP );
Debug.Log(enemyProfile.ToJSON);
}
public void OnButtonClickInInspectorLoadJSON()
{
// JSONを読込
enemyProfile.LoadJSON;
}
public void OnButtonClickInInspectorSaveJSON()
{
// JSONを読込
enemyProfile.SaveJSON;
}
}
EnemyEditor.cs
/*
* ./Editor/EnemyEditor.cs
*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(Enemy), true)]
public class EnemyEditor : Editor
{
[ContextMenu("SaveJSON")]
private void SaveJSON () {
script.OnButtonClickInInspectorSaveJSON();
}
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
Enemy script = target as Enemy;
if (GUILayout.Button("LoadJSON"))
{
script.OnButtonClickInInspectorLoadJSON();
}
}
}
Discussion