Version: 2018.4
Streaming Assets
Advanced Editor Topics

ScriptableObject

ScriptableObject 是什么?

ScriptableObject 是一个可独立于类实例来保存大量数据的数据容器。ScriptableObjects 的一个主要用例是通过避免重复值来减少项目的内存使用量。如果项目有一个预制件在附加的 MonoBehaviour 脚本中存储不变的数据,这将非常有用。每次实例化预制件时,都会产生单独的数据副本。这种情况下可以不使用该方法并且不存储重复数据,而是使用 ScriptableObject 来存储数据,然后通过所有预制件的引用访问数据。这意味着内存中只有一个数据副本。

与 MonoBehaviours 类似,ScriptableObjects 派生自 Unity 基对象,但不同于 MonoBehaviours 之处在于,不能将 ScriptableObject 附加到 GameObject。而是应该将它们保存为项目中的资源。

如果使用 Editor,可以在编辑时和运行时将数据保存到 ScriptableObjects,因为 ScriptableObjects 使用 Editor 命名空间和 Editor 脚本。但是,在已部署的构建中,不能使用 ScriptableObjects 来保存数据,但可以使用在开发期间设置的 ScriptableObject 资源中保存的数据。 从 Editor 工具作为资源保存到 ScriptableObjects 的数据将写入磁盘,因此将在会话之间一直保留。

使用 ScriptableObject

ScriptableObjects 的主要用例为:

  • 在 Editor 会话期间保存和存储数据
  • 将数据保存为项目中的资源,以便在运行时使用

要使用 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 文件夹中的任何预制件,然后在 Editor 中单击 Play。您将在使用 SpawnManagerScriptableObject 设置实例化的 Spawner 中看到引用的预制件。 定义了 ScriptableObject 派生类后,可以使用 CreateAssetMenu 属性,从而轻松地使用该类创建自定义资源。

提示:在 Inspector 中使用 ScriptableObject 引用时,可以双击引用字段来打开 ScriptableObject 的 Inspector。还可以创建自定义编辑器来定义该类型的 Inspector 外观,从而帮助管理它所代表的数据。


Streaming Assets
Advanced Editor Topics