知らなくてもゲームは作れる ScriptableObject ですが、上手く使えばメリットもある。
今回は、「実際に作ってみる」「利点・欠点」といった内容を紹介します。
実際に作って(使って)みる
物凄くザックリ言えば、大体こういう表(テーブル)を作り、編集・管理するものです。
この図よりはもう少し便利に使えますが、使えるようになるまでが面倒、そんな印象です。
以下の4ステップで使えるようになるので、試してみましょう!
青地の「列」部分を作る
Test.cs を作成し、以下をコピペしてください。
HumanList が、表(テーブル)データです。
using System.Collections.Generic; using UnityEngine; public class Test : ScriptableObject { /// <summary> /// 人データ /// </summary> [System.Serializable] public class HumanEntity { public string Name; public int Age; public int Sex; public float Height; public float Weight; public int Place; } public List<HumanEntity> HumanList = new List<HumanEntity>(); }
Scriptable Object を生成する
生成はちょっと面倒です。
以下の CreateTest.cs を Editor/ に入れ、Tools - Create ScriptableObject を行うと、Assets/Resources/Test.asset という ScriptableObject が生成されます。
生成された ScriptableObject はインスペクタで値を編集することができます。
using System.IO; using UnityEditor; public class CreateTest : EditorWindow { [MenuItem("Tools/Create ScriptableObject")] static void createScriptableObject() { string path = "Assets/Resources/Test.asset"; // なければ作る if (Directory.Exists("Assets/Resources/") == false) { Directory.CreateDirectory("Assets/Resources/"); } // なければ作る var data = (Test)AssetDatabase.LoadAssetAtPath(path, typeof(Test)); if (data == null) { Test table = CreateInstance<Test>(); AssetDatabase.CreateAsset(table, path); } AssetDatabase.Refresh(); } }
Scriptable Object を使いやすくする
性別(Sex)や出身地(Place)が数字だと、なんの事かわかりませんし、入力ミスも起こります。
それでは問題なので、Test.cs を変更します。
身長(Height)や体重(Weight)もついでにスライダーで選択できるようにしましょう。Unity Editor 拡張が使えます。
using System.Collections.Generic; using UnityEngine; public class Test : ScriptableObject { /// <summary> /// 出身地 /// </summary> public enum BirthPlace { Hokkaido, Niigata, Saitama, Nagoya, Tottori, Hiroshima, Yamaguchi, }; /// <summary> /// 性別 /// </summary> public enum Sex { Unknown, Male, Female, }; /// <summary> /// 人データ /// </summary> [System.Serializable] public class HumanEntity { public string Name; public int Age; public Sex Sex; [Range(0,200.0f)] public float Height; [Range(0,150.0f)] public float Weight; public BirthPlace Place; } public List<HumanEntity> HumanList = new List<HumanEntity>(); }
コードがコンパイルされると、自動的に Test.asset も変化します。これは便利!
enum が選択式のコンボボックスに、Range を指定した部分がスライダーになりました。
Test.cs を変更したからといって、前に入力したものが消えることもありません。
実行中にデータを取得する
再生中にデータを受け取れるかチェックします。
TestCheck.cs を作成し、以下をコピペ。
using UnityEngine; public class TestCheck { [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] static void testCheck() { Test test = Resources.Load<Test>("Test"); foreach (var entity in test.HumanList) { Debug.Log($"{entity.Name}: {entity.Sex}"); } } }
オブジェクトにアタッチするのが面倒なので RuntimeInitializeLoadType.BeforeSceneLoad 内メソッドとしましたが、同じことは Monobehaviour クラスの中でも当然可能です。
利点・欠点
このようなデータを扱うのであれば、json 形式(場合によっては csv も…?)がメジャーだと思うので、それと比較します。
利点
- インスペクタで値を編集できる
- enum やクラス内クラスなども扱えるので汎用性が高いし、コンボボックスやスライダーなどの入力も使える
- アクセスが速い
- バイナリ形式なので、データを解析・改ざんされにくい、ネタバレしづらい
欠点
- 作成が面倒。Test クラスは仕方ないとしても、CreateTest クラスを自作するのは…。
- unity にしかない。多フレームワーク展開している場合、他のフレームワークでは使えない
「初心者向けじゃない」導入のために、いまいち広まらないのは残念ですね。
導入さえこなしてしまえば、使いやすさはかなり高いので、是非使ってみてください。