ScriptableObject はスクリプト インスタンスから独立した大量の共有データを格納できるクラスです。SerializableObject と混同しがちですが,こちらはエディタ クラスであり,目的も違うものです。例えば integer が 1 万行ある配列のスクリプトのプレハブを作成したとします。配列は 4 MB のメモリを占有し,プレハブがオーナーとなります。プレハブをインスタンス化する毎に,その配列が複製されます。ゲームオブジェクトを 10 個作成した場合, 10 インスタンス合計で 40 MB となります。
全てのプリミティブ型,文字列,配列,リスト,Unity に特有の Vector 3 などの型,およびカスタム クラスを Unity は serialize 属性により宣言されたオブジェクトに属する 複製 としてシリアライズします。例えば SerializableObject を作成して integer が 1 万個だけ格納した場合,配列はそのインスタンスに格納されます。インスタンスは個別のデータのオーナーとして扱われます。ScriptableObject のフィールドや任意の UnityEngine.Object フィールドである MonoBehaviour, Mesh, GameObject 等は値でなく 参照 が格納されます。ScriptableObject は配列を格納します。ScriptableObject への参照がある プレハブのインスタンスが 10 個あり, 4 MB のデータを保有する場合,合計はあくまで 4 MB となり前例のように 40 MB とはなりません。
ScriptableObject を使用する場面は,値の複製をさけることでメモリ消費を節約するときですが,プラグ可能なデータセットを定義することにも使用できます。例を挙げると RPG における NPC キャラクターのショップです。例えばカスタムの ShopContents ScriptableObject で複数のアセット作成して,各々で購入可能なアイテムを定義できます。ゲームに 3 つのゾーンがあると仮定すると,各々のゾーンで異なるレベルのアイテムを提供できます。ショップのスクリプトの中で ShopContents オブジェクトを参照して利用可能なアイテムを定義できます。サンプルについてはスクリプティング リファレンスを参照して下さい。
Tips: インスペクタ上で ScriptableObject からの参照を扱う場合,参照フィールドをダブルクリックして ScriptableObject を開きます。またカスタムのエディタを作成して,その型が表すデータが管理しやすいようにインスペクタの外見を定義できます。