Version: 2019.1
ストリーミングアセット
エディターの高度なトピック

ScriptableObject

ScriptableObject とは

ScriptableObject は、クラスインスタンスとは無関係に、大量のデータを保存するために使用できるデータコンテナです。ScriptableObject の主な使用例の 1 つは、値に対し複数のコピーを避けることによってプロジェクトのメモリ消費を削減することです。これは、プロジェクトに、プレハブ (同じデータをアタッチした MonoBehaviour スクリプトに格納します) がある場合に便利です。プレハブは、インスタンス化するたびにそれぞれがデータのコピーを作成します。この方法を使ってデータの複数のコピーを格納する代わりに、ScriptableObject を使用してデータを格納すると、すべてのプレハブから参照を使ってアクセスすることができます。つまり、メモリ内にデータのコピーが 1 回ですみます。

MonoBehaviour と同様に、ScriptableObject は基本的な Unity オブジェクトから派生しますが、MonoBehaviour と異なり、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++;
        }
    }
}

上記のスクリプトを シーン のゲームオブジェクトにアタッチします。次に、インスペクターで、Spawn Manager Values フィールドが設定した新しい SpawnManagerScriptableObject になるように設定します。 Entity To Spawn フィールドを Assets フォルダー内のプレハブのいずれかに設定し、エディターで 再生 をクリックします。Spawner で参照したプレハブが SpawnManagerScriptableObject の設定を使ってインスタンス化されます。 CreateAssetMenu 属性を使用すると、クラスを使用してカスタムアセットを簡単に作成できます。

ヒント: インスペクターで ScriptableObject の参照を扱う場合、参照フィールドをダブルクリックして ScriptableObject のインスペクターを開きます。またカスタムのエディターを作成して、データを管理しやすいようにインスペクターを好みの外見に定義できます。


ストリーミングアセット
エディターの高度なトピック