Version: Unity 6.0 (6000.0)
语言 : 中文
MonoBehaviour
Unity 特性

ScriptableObject

Switch to Scripting

ScriptableObject 是一个可独立于类实例来保存大量数据的数据容器。ScriptableObject 的一个主要用途是通过避免重复值来减少项目的内存使用量。如果项目有一个预制件在附加的 MonoBehaviour 脚本中存储不变的数据,这将非常有用。

每次实例化预制件时,都会产生单独的数据副本。这种情况下可以不使用该方法并且不存储重复数据,而是使用 ScriptableObject 来存储数据,然后通过所有预制件的引用访问数据。这意味着内存中只有一个数据副本。

就像 MonoBehaviour 一样,ScriptableObject 派生自基本 UnityEngine.Object,但不同于 MonoBehaviour 之处在于,不能将 ScriptableObject 附加到游戏对象。正确的做法是需要将它们保存为项目中的资源。

如果使用 Unity Editor,可以在编辑时和运行时将数据保存到 ScriptableObjects,因为 ScriptableObjects 使用 Editor 命名空间和 Editor 脚本。但是,在已部署的构建中,不能使用 ScriptableObject 来保存数据,但可以使用在开发期间设置的 ScriptableObject 资源中保存的数据。

将来自 Editor 的数据在作为资源保存到 ScriptableObject 时,Unity 将数据写入磁盘,且其会在会话之间一直保留。

此页面概述了 ScriptableObject 类及其在脚本编写中的常见用法。有关 ScriptableObject 类的每个成员的详尽参考,请参阅 ScriptableObject 脚本参考

使用 ScriptableObject

ScriptableObjects 的主要用例为:

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

ScriptableObject 必须继承自 ScriptableObject 类。

要创建新的 ScriptableObject 脚本,请执行以下操作之一:

  • 在主菜单中,转到资源 (Assets) > 创建 (Create) > 脚本 (Scripting) >,然后选择 ScriptableObject Script
  • Project 窗口工具栏中,右键单击以打开 Project 窗口上下文菜单,然后选择创建 (Create) > 脚本 (Scripting) > ScriptableObject 脚本(ScriptableObject Script)。还可以单击 Project 窗口中的加号来直接打开创建 (Create) 菜单。

可以使用 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
{
    // 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++;
        }
    }
}

注意:脚本文件与类的名称必须相同。

将先前的脚本附加到场景中的游戏对象。然后,在 Inspector 中,将 Spawn Manager Values 字段设置为新设置的 SpawnManagerScriptableObject

Entity To Spawn 字段设置为 Assets 文件夹中的任何预制件,然后在 Editor 中单击 Play。在 Spawner 中引用的预制件会使用在 SpawnManagerScriptableObject 实例中设置的值来实例化。

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

其他资源

MonoBehaviour
Unity 特性