ScriptableObject は、クラスのインスタンスとは独立した大量のデータを保存するためのデータコンテナです。ScriptableObject の主な使用例の 1 つに、値のコピーを避けてプロジェクトのメモリ使用量を減らすことがあります。これは、プロジェクトに プレハブ があり、設定された MonoBehaviour スクリプトに不変のデータを保存している場合に有効です。
そのプレハブをインスタンス化するたびにそのデータのコピーを取得します。メソッドを使って重複したデータを保存するのではなく、ScriptableObject を使ってデータを保存し、すべてのプレハブから参照によってアクセスできます。つまり、メモリ内にはデータのコピーが 1 つしかないということです。
MonoBehaviour と同様に、ScriptableObject は基本的な Unity オブジェクトから派生しますが、MonoBehaviour と異なり、ScriptableObject を ゲームオブジェクト にアタッチすることはできません。代わりに、プロジェクトのアセットとして保存する必要があります。
エディターを使用する場合、ScriptableObject はエディターの名前空間やスクリプトを使用するため、編集中やランタイムにデータを ScriptableObject に保存することができます。ただし、デプロイされたビルドでは、ScriptableObject を使ってデータを保存することはできませんが、開発時に設定した ScriptableObject のアセットから保存されたデータを使用できます。
エディターツールから ScriptableObject にアセットとして保存したデータは、ディスクに書き込まれます。そのため、セッション間で永続的です。
このページでは、ScriptableObject クラスの概要と、このクラスを使ってスクリプトを作成する際の一般的な使い方について説明します。ScriptableObject クラスのすべてのメンバーを参照するには、ScriptableObject のスクリプトリファレンス を参照してください。
ScriptableObject の主な使用例は以下のとおりです。
ScriptableObject を使用するには、アプリケーションの Assets フォルダーにスクリプトを作成し、それに ScriptableObject
クラスを継承させます。CreateAssetMenu 属性を使用すると、クラスを使用して簡単にカスタムアセットを作成できます。以下はその例です。
using UnityEngine;
[CreateAssetMenu(fileName = "Data", menuName = "ScriptableObjects/SpawnManagerScriptableObject", order = 1)]
public class SpawnManagerScriptableObject : ScriptableObject
{
public string prefabName;
public int numberOfPrefabsToCreate;
public Vector3[] spawnPoints;
}
Assets フォルダー内に作成した上のスクリプトを使用して、Assets > Create > ScriptableObjects > SpawnManagerScriptableObject の順に選択し、ScriptableObject のインスタンスを作成できます。新しい ScriptableObject インスタンスに分かりやすい名前をつけ、値を変更します。これらの値を使用するには、ScriptableObject を参照する新しいスクリプト (この場合は SpawnManagerScriptableObject
) を作成する必要があります。以下はその例です。
using UnityEngine;
public class Spawner : MonoBehaviour
{
// インスタンス化するゲームオブジェクト
public GameObject entityToSpawn;
// 上で定義した ScriptableObject のインスタンス
public SpawnManagerScriptableObject spawnManagerValues;
// 作成されたエンティティの名に追加され、それぞれが作成されるたびにインクリメントされます。
int instanceNumber = 1;
void Start()
{
SpawnEntities();
}
void SpawnEntities()
{
int currentSpawnPointIndex = 0;
for (int i = 0; i < spawnManagerValues.numberOfPrefabsToCreate; i++)
{
// 現時点のスポーン位置でプレハブのインスタンスを作成します。
GameObject currentEntity = Instantiate(entityToSpawn, spawnManagerValues.spawnPoints[currentSpawnPointIndex], Quaternion.identity);
// インスタンス化したエンティティの名前が ScriptableObject で定義した文字列になるように設定し、次に、固有の番号を追加します。
currentEntity.name = spawnManagerValues.prefabName + instanceNumber;
// スポーン位置の次のインデックスに移動します。インデックスを超えた場合は、最初に戻ります。
currentSpawnPointIndex = (currentSpawnPointIndex + 1) % spawnManagerValues.spawnPoints.Length;
instanceNumber++;
}
}
}
ノート: スクリプトファイルは、クラスと同じ名前でなければなりません。
上記のスクリプトを、シーン の ゲームオブジェクトにアタッチします。次に、Inspector で Spawn Manager Values フィールドに、用意した新しい SpawnManagerScriptableObject
を設定します。
Entity To Spawn フィールドを Assets フォルダー内の任意のプレハブに設定し、エディターで 再生 をクリックします。Spawner
で参照したプレハブは、SpawnManagerScriptableObject
インスタンスで設定した値を使ってインスタンス化されます。
ヒント: インスペクターで ScriptableObject の参照を扱う場合、参照フィールドをダブルクリックして ScriptableObject のインスペクターを開きます。またカスタムのエディターを作成して、データを管理しやすいようにインスペクターを好みの外見に定義できます。