ScriptableObjectの中にScriptableObjectを入れる方法
この記事はさいたまげーむす Advent Calendar 2016 11日目の記事です。
通常、ScriptableObjectにはSerializableなものを格納することができますが、ほかのクラスオブジェクトは一度は入れることはできるものの、一度再生してしまうと情報を失ってしまいます。
そのため、ScriptableObejctの中にクラスごとデータを入れたい場合、そのクラスもScriptableObjectにする必要があります。その手法を紹介しましょう。
using UnityEngine; using System.Linq; using UnityEditor; using System.Collections.Generic; class ObjA : ScriptableObject { public int blah1; public bool blah2; public string blah3; } class ObjB : ScriptableObject { public List<ObjA> objs = new List<ObjA>(); } [MenuItem("Tools/Create SO")] public static void CreateScriptableObject() { const string path = "Assets/B.asset"; var b = ScriptableObject.CreateInstance<ObjB>(); for (int i = 0; i < 10; ++i) { var a = ScriptableObject.CreateInstance<ObjA>(); // プロジェクトビューで表示される名前 a.name = string.Format("a[{0}]", i); b.objs.Add(a); } // create AssetDatabase.CreateAsset(b, path); // アセットとして作成済みのものに対して追加する for (int i = 0; i < 10; ++i) { AssetDatabase.AddObjectToAsset(b.objs[i], path); } // アセットを再インポートして反映させる(これをしない場合、プロジェクトを保存するまで反映されない) AssetDatabase.ImportAsset(path); }
このスクリプトをEditorフォルダ内に入れてTools > Create SOを実行してみてください。これなら何度実行しても情報は失われません。
一度アセットとして書き出して、そこに追加する形ですね。
解説は大体コードのコメントに書きました。いつか使う時が来るかもしれない。