Unity - CSVファイルのデータを Scriptable Object に流し込む -
初めに
Unity では Scriptable Object と呼ばれるデータが保存されたオブジェクトを作ることができます。本記事は CSVファイルのデータから Scriptable Object を生成する方法についての記事になります。
Index
Scriptable Object
Scriptable Object
上の画像のように、データを保存することができるオブジェクトになります。データを取得する際、毎回CSVファイルなどからデータを読み込むと処理が重くなります。そこであらかじめ Scriptable Object にデータを流し込み、保存しておくことでメモリの節約につながります。
CSVファイルのデータを Scriptable Object に流し込む
スクリプトの用意
次の2つのスクリプトを用意します。以前の記事では、 [System.Serializable]属性をつけたクラス(CharaData のクラス)を同じスクリプト内に書いていましたが、今回は別のスクリプトに分けています。
〇ScriptableObjectになるクラスを定義、[System.Serializable]属性をつけたクラスを記述したスクリプト
using System.Collections; using System.Collections.Generic; using UnityEngine; public class CharaDataBase : ScriptableObject { public CharaData[] datas; } [System.Serializable] public class CharaData { public string name; public int Hp; public int Power; }
〇CSVファイルを読み込み、Scriptable Object を生成、更新するためのスクリプト
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEditor; #if UNITY_EDITOR public class PostProcessingTest : AssetPostprocessor { static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths) { foreach (string str in importedAssets) { // IndexOfの引数は"/(読み込ませたいファイル名)"とする。 if (str.IndexOf("/CSVTestData.csv") != -1) { Debug.Log("CSVファイルがあった!!!"); // Asset直下から読み込む(Resourcesではないので注意) TextAsset textasset = AssetDatabase.LoadAssetAtPath<TextAsset>(str); // 同名のScriptableObjectファイルを読み込む。ない場合は新たに作る。 string assetfile = str.Replace(".csv", ".asset"); CharaDataBase cd = AssetDatabase.LoadAssetAtPath<CharaDataBase>(assetfile); if (cd == null){ cd = new CharaDataBase(); AssetDatabase.CreateAsset(cd, assetfile); } cd.datas = CSVSerializer.Deserialize<CharaData>(textasset.text); EditorUtility.SetDirty(cd); AssetDatabase.SaveAssets(); } } } } #endif
MonoBehaviour ではなく AssetPostprocessor のコンポーネントを利用しています。これは、Project 内のファイルに変更があった場合に呼び出されます。OnPostprocessAllAssets は Assets 内のファイルがインポート、削除、移動した場合に呼び出されるため、そこに CSVファイルの読み込み、Scriptable Object に保存する処理を書いています。
Scriptable Object に保存したデータが消える
The associated script can not be loaded. と表示され、保存したデータが消えることがおきました。その原因は ”スクリプト名と Scriptable Object継承クラス名が一致していないかったから" でした。
本記事では、CharaDataBase で統一しなければいけなかった。
Scriptable Object のデータをスクリプトから取得する
Scriptable Object のデータを取得し、コンソールにログを表示してみます。
次のスクリプトをゲームオブジェクトにつけます。
Scriptable Object は Scriptable Object継承クラス名を public もしくは SerializeField で取得します。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class CharaTestScript : MonoBehaviour { //Scriptable Object を取得 [SerializeField] CharaDataBase charabase; // Start is called before the first frame update void Start() { for(int i = 0; i < charabase.datas.Length; i++) { Debug.Log("Name:" + charabase.datas[i].name + ", Hp:" + charabase.datas[i].Hp + ", Power:" + charabase.datas[i].Power); } } }
あとは、ドラッグ&ドロップをし、実行すれば ok です。
(実行結果)