# ScriptableObject

> Inherit from ScriptableObject to store data that's independent of GameObjects.

ScriptableObject は、クラスのインスタンスとは独立した大量のデータを保存するために使用できるデータコンテナです。ScriptableObject の主な使用例の 1 つは、値に対し複数のコピーが作成されることを回避することによってプロジェクトのメモリ消費を削減することです。これは、プロジェクトにプレハブがあり、設定された MonoBehaviour スクリプトに不変のデータを保存している場合に有効です。

そのプレハブをインスタンス化するたびにそのデータのコピーを取得します。この方法を使用して複製されたデータを格納する代わりに、ScriptableObject を使用してデータを格納すると、すべてのプレハブから参照によってアクセスすることができます。つまり、メモリ内にデータのコピーが 1 つのみ存在します。

MonoBehaviour と同様に、ScriptableObject は基本的な `UnityEngine.Object` から派生しますが、MonoBehaviour と異なり、ScriptableObject を[ゲームオブジェクト](/engine/6000.0/manual/scripting/get-started/fundamental-unity-types/class-game-object.md)にアタッチすることはできません。代わりに、プロジェクトのアセットとして保存する必要があります。

Unity エディターを使用する場合、ScriptableObject はエディターの名前空間やスクリプトを使用するため、編集中やランタイムにデータを ScriptableObject に保存することができます。ただし、デプロイされたビルドでは、ScriptableObject を使用してデータを保存することはできませんが、開発時に設定した ScriptableObject のアセットから保存されたデータを使用できます。

エディターツールから ScriptableObject にアセットとして保存したデータは、ディスクに書き込まれます。そのため、セッション間で永続的です。

このページでは、ScriptableObject クラスの概要と、このクラスを使用してスクリプトを作成する際の一般的な使用方法について説明します。ScriptableObject クラスのすべてのメンバーの詳細なリファレンスについては、[ScriptableObject スクリプトリファレンス](/engine/6000.0/script-reference/unity-engine/scriptable-object.md)を参照してください。

## ScriptableObject の使用

ScriptableObject の主な使用例は以下のとおりです。

* エディターセッション中のデータの保存
* プロジェクトのデータをアセットとして保存し、ランタイムに使用

ScriptableObject は [ScriptableObject](/engine/6000.0/script-reference/unity-engine/scriptable-object.md) クラスから継承する必要があります。

新しい ScriptableObject スクリプトを作成するには、以下のいずれかを実行します。

* メインメニューで、**Assets** > **Create** > **Scripting** の順に移動し、**ScriptableObject Script** を選択します。
* [Project ウィンドウツールバー](/engine/6000.0/manual/unity-editor/using-the-editor/project-view.md)で、右クリックして Project ウィンドウのコンテキストメニューを開き、**Create** > **Scripting** > **ScriptableObject Script** の順に選択します。Project ウィンドウでプラス記号をクリックして、直接 **Create** メニューを開くこともできます。

[CreateAssetMenu](/engine/6000.0/script-reference/unity-engine/create-asset-menu-attribute.md) 属性を使用して、クラスを使用するカスタムアセットを作成できます。 例:

```
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
{
    // The GameObject to instantiate.
    public GameObject entityToSpawn;

    // An instance of the ScriptableObject defined above.
    public SpawnManagerScriptableObject spawnManagerValues;

    // This will be appended to the name of the created entities and increment when each is created.
    int instanceNumber = 1;

    void Start()
    {
        SpawnEntities();
    }

    void SpawnEntities()
    {
        int currentSpawnPointIndex = 0;

        for (int i = 0; i < spawnManagerValues.numberOfPrefabsToCreate; i++)
        {
            // Creates an instance of the prefab at the current spawn point.
            GameObject currentEntity = Instantiate(entityToSpawn, spawnManagerValues.spawnPoints[currentSpawnPointIndex], Quaternion.identity);

            // Sets the name of the instantiated entity to be the string defined in the ScriptableObject and then appends it with a unique number. 
            currentEntity.name = spawnManagerValues.prefabName + instanceNumber;

            // Moves to the next spawn point index. If it goes out of range, it wraps back to the start.
            currentSpawnPointIndex = (currentSpawnPointIndex + 1) % spawnManagerValues.spawnPoints.Length;

            instanceNumber++;
        }
    }
}
```

> **注意** スクリプトファイルは、クラスと同じ名前でなければなりません。

前述のスクリプトを[シーン](/engine/6000.0/manual/working-in-unity/working-with-scenes/creating-scenes.md)のゲームオブジェクトにアタッチします。次に、Inspector で、**Spawn Manager Values** フィールドを設定した新しい `SpawnManagerScriptableObject` に設定します。

**Entity To Spawn** フィールドを Assets フォルダー内の任意のプレハブに設定し、エディターで **Play** をクリックします。`Spawner` で参照したプレハブは、`SpawnManagerScriptableObject` インスタンスで設定した値を使用してインスタンス化します。

Inspector で ScriptableObject の参照を扱う場合は、参照フィールドをダブルクリックして ScriptableObject の Inspector を開きます。カスタムのエディターを作成して、表すデータを管理しやすいように Inspector を好みの外見に定義することもできます。

## 追加リソース

* [ScriptableObject API リファレンス](/engine/6000.0/script-reference/unity-engine/scriptable-object.md)
* [ScriptableObject 入門](https://learn.unity.com/tutorial/introduction-to-scriptable-objects)
