知らなくてもゲームは作れる 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 にしかない。多フレームワーク展開している場合、他のフレームワークでは使えない
「初心者向けじゃない」導入のために、いまいち広まらないのは残念ですね。
導入さえこなしてしまえば、使いやすさはかなり高いので、是非使ってみてください。


