包含此页的版本:
不含此页的版本:
ScriptableObject 是一个可序列化的 Unity 类型,派生自UnityEngine.Object.与 MonoBehaviour 一样,您不会直接实例化 ScriptableObject 类,而是创建从它派生的自定义 C# 类,然后创建这些自定义类的实例,通常通过 Unity 编辑器中的 Assets 菜单。
从 ScriptableObject 派生的所有类实例通常称为 ScriptableObjects。与 MonoBehaviour 不同,ScriptableObjects 不附加到游戏对象Unity 场景中的基本对象,可以表示角色、道具、风景、相机、航路点等。游戏对象的功能由附加到它的组件定义。更多信息
请参阅术语表作为组件,但在项目中以资产 可以在游戏或项目中使用的任何媒体或数据。资产可能来自在 Unity 外部创建的文件,例如 3D 模型、音频文件或图像。您还可以在 Unity 中创建一些资产类型,例如动画师控制器、混音器或渲染纹理。更多信息
请参阅术语表,独立于游戏对象。因为 ScriptableObjects 继承自UnityEngine.Object,您可以将它们的实例拖动或拾取到检查器一个 Unity 窗口,显示有关当前选定游戏对象、资产或项目设置的信息,允许您检查和编辑值。更多信息
请参阅术语表.
ScriptableObject 的主要值是作为数据存储,但它们也可以定义行为。ScriptableObjects 的一个常见用途是作为多个对象在运行时使用的共享数据的容器,这可以通过避免值的副本来减少项目的内存使用。
例如,如果您的项目具有预制件:一种资产类型,允许您存储包含组件和属性的游戏对象。预制件充当模板,你可以从中在场景中创建新的对象实例。更多信息
请参阅术语表将不变的数据存储在附加的 MonoBehaviour 中脚本一段代码,允许您创建自己的组件、触发游戏事件、随时间修改组件属性以及以您喜欢的任何方式响应用户输入。更多信息
请参阅术语表,则预制件的每个新实例都会获得自己的数据副本。您可以使用 ScriptableObject 来存储数据,然后从所有预制件通过引用访问它,而不是像这样复制数据。这意味着内存中有一个数据副本。
ScriptableObjects 的主要用例是:
EditorTool和EditorWindow衍生ScriptableObject.有关 ScriptableObject 类的每个成员的完整参考,请参阅 ScriptableObject 脚本参考。
要创建新的 ScriptableObject 脚本,最快的方法是通过以下方式之一使用 资产(Assets) 菜单中的预定义 ScriptableObject 脚本模板:
这为您提供了一个继承自UnityEngine.ScriptableObject.然后,你可以使用 CreateAssetMenu 属性创建此类的实例,每个实例都成为项目中的资产。
以下示例使用 ScriptableObject 来存储在创作时定义的数据,这些数据稍后用于确定在运行时实例化预制件的位置。首先,在Assets文件夹:
// Define a base ScriptableObject class called SpawnManagerScriptableObject
using UnityEngine;
// Use the CreateAssetMenu attribute to allow creating instances of this ScriptableObject from the Unity Editor.
[CreateAssetMenu(fileName = "Data", menuName = "ScriptableObjects/SpawnManagerScriptableObject", order = 1)]
public class SpawnManagerScriptableObject : ScriptableObject
{
public string prefabName;
public int numberOfPrefabsToCreate;
public Vector3[] spawnPoints;
}
使用上一个脚本Assets文件夹中,通过导航到 资产(Assets) > 创建 > 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 中,使用 新的.asset实例SpawnManagerScriptableObject您设置的。
将 Entity To Spawn 字段设置为Assets文件夹,然后进入播放模式。您在Spawner使用您在SpawnManagerScriptableObject实例。
如果您在检查器中使用 ScriptableObject 引用,则可以双击引用字段以打开 ScriptableObject 的检查器。您还可以为您的类型创建自定义检查器,以帮助管理它所表示的数据。
在 Unity 编辑器中,您可以在编辑模式和播放模式下将数据保存到 ScriptableObjects。在运行时的独立播放器中,你只能从 ScriptableObject 资产中读取保存的数据。当您使用编辑器创作工具或 Inspector 修改 ScriptableObject 资源时,Unity 会自动将数据写入磁盘,并在编辑器会话之间保留。
但是,Unity 不会自动将更改保存到ScriptableObject在编辑模式下通过脚本制作。在这些情况下,您必须调用EditorUtility.SetDirty确保 Unity 的序列化系统将其识别为已更改并将更改保存到磁盘。否则,更改可能不会在编辑器会话之间持续存在。
假设你有以下名为GameSettings:
using UnityEngine;
[CreateAssetMenu]
public class GameSettings : ScriptableObject
{
public int highScore;
}
如果你有一个编辑器脚本,可以将highScore值,请确保包含对EditorUtility.SetDirty如下所示:
// Save this as Assets/Editor/GameSettingsEditor.cs
using UnityEditor;
using UnityEngine;
public class GameSettingsEditor : EditorWindow
{
GameSettings settings;
[MenuItem("Window/Game Settings Editor")]
public static void ShowWindow()
{
GetWindow<GameSettingsEditor>("Game Settings Editor");
}
void OnGUI()
{
settings = EditorGUILayout.ObjectField("Settings", settings, typeof(GameSettings), false) as GameSettings;
if (settings == null) return;
EditorGUILayout.LabelField("High Score", settings.highScore.ToString());
if (GUILayout.Button("Increase High Score"))
{
settings.highScore += 10;
// Call SetDirty to ensure the change is saved
EditorUtility.SetDirty(settings);
// Optional: AssetDatabase.SaveAssets(); // To save immediately
}
}
}
无需调用SetDirty,则更改为highScore显示在内存中,但如果关闭并重新打开编辑器,该值将恢复为其先前的值。