版本: Unity 6 (6000.0)
语言英语
  • C#

ScriptableObject

UnityEngine 中的类

/

继承自:Object

/

实现于:UnityEngine.CoreModule

建议更改

成功!

感谢您帮助我们提升 Unity 文档的质量。虽然我们无法接受所有提交内容,但我们确实阅读了用户提出的每项更改建议,并在适用的情况下进行更新。

关闭

提交失败

由于某些原因,您的更改建议无法提交。请<a>稍后再试</a>。感谢您抽出时间帮助我们提升 Unity 文档的质量。

关闭

取消

切换到手册

描述

如果您想创建独立于游戏对象的物体,可以从该类派生。

使用 ScriptableObjects 以集中方式管理数据,以便从项目中的场景和资源中方便地访问这些数据。

使用 CreateInstance 实例化 ScriptableObject 对象。

您可以将 ScriptableObjects 保存到资源文件,方法是使用编辑器 UI(请参见 CreateAssetMenuAttribute),或从脚本调用 AssetDatabase.CreateAsset。您也可以从 ScriptedImporter 生成 ScriptableObjects 作为输出。请参见 AssetImportContext.AddObjectToAsset

如果 ScriptableObject 未保存到资源,并且它被场景中的对象引用,则 Unity 会将其直接序列化到场景文件。对于在项目中只有一个持久实例的 ScriptableObjects,请使用 ScriptableSingleton<T0> 基类。

使用 AssetDatabase 访问之前保存的对象,例如 AssetDatabase.LoadAssetAtPath。当 ScriptableObject 被 MonoBehaviour 上的字段引用时,ScriptableObject 会自动加载,因此脚本只需使用字段的值即可访问它。

ScriptableObject 的 C# 字段的序列化方式与 MonoBehaviour 上的字段完全相同,有关详细信息,请参考 脚本序列化。包含大型数组或其他可能包含大量数据的类应使用 PreferBinarySerialization 属性声明,因为 YAML 不是此类数据的有效表示形式。

ScriptableObject 调用 Destroy 会释放与其关联的本机资源,但对象会保留在内存中,直到被垃圾回收。处于这种分离状态的对象将显示为 null,尽管实际上并非如此。但是,此类不支持 空条件运算符 ?.)和 空合并运算符 ??)。

以下示例演示了 ScriptableObject 的典型用法:不同类型的车辆参数在派生自 ScriptableObject 的 VehicleTypeInfo 类字段中表示。每种类型的车辆将拥有自己的资源文件,其中参数值将根据类型进行适当设置。游戏中的每个车辆实例都将引用与其类型相对应的资源,而不是保留每个参数的冗余副本。这种设计便于在中央位置调整车辆行为。它对性能也有好处,尤其是在共享数据量很大的情况下。

示例的第一个脚本实现了一个派生自 ScriptableObject 的类。

using UnityEngine;

[CreateAssetMenu] public class VehicleTypeInfo : ScriptableObject { // Class that represents a specific type of vehicle [Range(0.1f, 100f)] public float m_MaxSpeed = 0.1f;

[Range(0.1f, 10f)] public float m_MaxAcceration = 0.1f;

// This class could have many other vehicle parameters, such as Turning Radius, Range, Damage etc }

第二个脚本实现了一个使用 ScriptableObject 的 MonoBehaviour。

using UnityEngine;
using UnityEditor;

public class VehicleInstance : MonoBehaviour { // Snippet of a MonoBehaviour that would control motion of a specific vehicle. // In PlayMode it accelerates up to the maximum speed permitted by its type

[Range(0f, 200f)] public float m_CurrentSpeed;

[Range(0f, 50f)] public float m_Acceleration;

// Reference to the ScriptableObject asset public VehicleTypeInfo m_VehicleType;

public void Initialize(VehicleTypeInfo vehicleType) { m_VehicleType = vehicleType; m_CurrentSpeed = 0f; m_Acceleration = Random.Range(0.05f, m_VehicleType.m_MaxAcceration); }

void Update() { m_CurrentSpeed += m_Acceleration * Time.deltaTime;

// Use parameter from the ScriptableObject to control the behaviour of the Vehicle if (m_VehicleType && m_VehicleType.m_MaxSpeed < m_CurrentSpeed) m_CurrentSpeed = m_VehicleType.m_MaxSpeed;

gameObject.transform.position += gameObject.transform.forward * Time.deltaTime * m_CurrentSpeed; } }

public class ScriptableObjectVehicleExample { [MenuItem("Example/Setup ScriptableObject Vehicle Example")] static void MenuCallback() { // This example programmatically performs steps that would typically be performed from the Editor's user interface // to creates a simple demonstration. When going into Playmode the three objects will move according to the limits // set by their vehicle type.

// Step 1 - Create or reload the assets that store each VehicleTypeInfo object. VehicleTypeInfo wagon = AssetDatabase.LoadAssetAtPath<VehicleTypeInfo>("Assets/VehicleTypeWagon.asset"); if (wagon == null) { // Create and save ScriptableObject because it doesn't exist yet wagon = ScriptableObject.CreateInstance<VehicleTypeInfo>(); wagon.m_MaxSpeed = 5f; wagon.m_MaxAcceration = 0.5f; AssetDatabase.CreateAsset(wagon, "Assets/VehicleTypeWagon.asset"); }

VehicleTypeInfo cruiser = AssetDatabase.LoadAssetAtPath<VehicleTypeInfo>("Assets/VehicleTypeCruiser.asset"); if (cruiser == null) { cruiser = ScriptableObject.CreateInstance<VehicleTypeInfo>(); cruiser.m_MaxSpeed = 75f; cruiser.m_MaxAcceration = 2f; AssetDatabase.CreateAsset(cruiser, "Assets/VehicleTypeCruiser.asset"); }

// Step 2 - Create some example vehicles in the current scene { var vehicle = GameObject.CreatePrimitive(PrimitiveType.Sphere); vehicle.name = "Wagon1"; var vehicleBehaviour = vehicle.AddComponent<VehicleInstance>(); vehicleBehaviour.Initialize(wagon); }

{ var vehicle = GameObject.CreatePrimitive(PrimitiveType.Sphere); vehicle.name = "Wagon2"; var vehicleBehaviour = vehicle.AddComponent<VehicleInstance>(); vehicleBehaviour.Initialize(wagon); }

{ var vehicle = GameObject.CreatePrimitive(PrimitiveType.Cube); vehicle.name = "Cruiser1"; var vehicleBehaviour = vehicle.AddComponent<VehicleInstance>(); vehicleBehaviour.Initialize(cruiser); } } }

静态方法

CreateInstance创建可脚本化对象的实例。

消息

Awake在创建 ScriptableObject 实例时调用。
OnDestroy当可脚本化对象将被销毁时调用此函数。
OnDisable当可脚本化对象超出范围时调用此函数。
OnEnable当对象加载时调用此函数。
OnValidate仅在编辑器中使用的函数,在加载脚本或检查器中的值发生变化时,Unity 会调用该函数。
Reset重置为默认值。

继承的成员

属性

hideFlags对象是否应该隐藏、与场景一起保存或用户可修改?
name对象的名称。

公共方法

GetInstanceID获取对象的实例 ID。
ToString返回对象的名称。

静态方法

Destroy删除游戏对象、组件或资源。
DestroyImmediate立即销毁对象 obj。强烈建议使用 Destroy 代替。
DontDestroyOnLoad加载新场景时,不要销毁目标对象。
FindAnyObjectByType检索任何已加载的活动对象类型。
FindFirstObjectByType检索第一个已加载的活动对象类型。
FindObjectsByType检索所有已加载的对象类型的列表。
Instantiate克隆原始对象并返回克隆。
InstantiateAsync捕获原始对象(必须与某个游戏对象相关)的快照,并返回 AsyncInstantiateOperation。

运算符

bool对象是否存在?
operator !=比较两个对象是否引用不同的对象。
operator ==比较两个对象引用,查看它们是否引用同一个对象。