有没有办法让脚本将对象作为字段引用?
Is there a way to have a script reference an object as a field?
我四处搜索时遇到了麻烦,可能严重误解了 Unity 希望您构建项目的方式,但这是我的情况:
我的游戏中有角色,想在编辑器中配置它们。我制作了 类 代表不同的行为类型和可以执行的操作。 有没有办法让我在为这些 类 输入的脚本上创建一个字段,以便我可以使用检查器拖放来配置不同的预制件?
下面是一些演示情况的代码:
Unit.cs
// A unit on the board.
public class Unit : MonoBehaviour
{
public UnitAction action;
}
UnitAction.cs
// A unit on the board.
public class UnitAction : MonoBehaviour
{
// Does things
}
将此脚本应用到预制件后,这些字段会显示在检查器中,但没有填充默认字段值的选项。如果我将字段类型设置为 UnityEngine.Object
,我可以将脚本放在那里,但这似乎是我不想要的。
我猜你不希望这些脚本暴露在编辑器之外,所以你可以使用一个名为 SerializeField
的属性。它会将字段公开给编辑器,以便您可以拖入引用,但其他脚本将无法访问您放入的字段。
如果你想让特定的脚本出现在编辑器中,只需写
[SerializeField] private YourScriptName scriptReference = null;
由于列表是通用结构,如果你愿意,你也可以用类似的方式制作脚本列表
[SerializeField] private List<YourScriptName> scriptListReference = new List<YourScriptName>();
因为我不认为你会再次分配这些引用,如果你想在任何时候获取引用,你可以制作一个 getter 方法。
public YourScriptName GetYourScript(){ return scriptReference;}
很少有Unity无法序列化的字段,所以一般来说,如果你想拖入对组件、脚本、对象等的引用,你需要做的就是让它成为SerializeField
或 public 后跟要拖入的任何类型。
来自文档,序列化系统
CANNOT serialize static fields.
CANNOT serialize properties.
CAN serialize public non-static fields (of serializable types)
CAN serialize nonpublic non-static fields marked with the SerializeField attribute.
它可以序列化的字段如下
- 所有 类 继承自 UnityEngine.Object,例如
游戏对象、组件、MonoBehaviour、Texture2D、AnimationClip。
- 所有基本数据类型,如 int、string、float、bool。
- 一些内置类型,例如 Vector2、Vector3、Vector4、Quaternion、Matrix4x4、Color、Rect、LayerMask。
- 可序列化类型的数组 a 的列表
可序列化类型
- 枚举
- 结构
听起来您正在尝试序列化对脚本本身的引用而不是那些脚本的实例。您可能希望通过多种方式执行此操作:
您可以将您的 UnitAction 脚本作为 GameObject 的组件附加到您的“Unit”对象可访问的上下文中(在同一场景中,“Unit”对象的子对象,或者 -可能是最常见的情况——“Unit”对象本身)。然后,您将能够将这些实例化组件序列化到您的 Unit class 中的字段中。这是最常见的用例。
您可以为每个 UnitAction 组件创建一个预制件,然后将这些预制件序列化到您的 Unit class 字段中。然后您将在运行时实例化一个 UnitAction。根据您的描述,这似乎并不适合您的情况,因为 UnitAction 可能不是需要动态实例化的东西,但了解这一点很重要。本文有一个使用此方法为单位提供法术列表的示例(并且还提供了一些关于如何考虑使用可能对您有价值的统一组件的良好背景):
我四处搜索时遇到了麻烦,可能严重误解了 Unity 希望您构建项目的方式,但这是我的情况:
我的游戏中有角色,想在编辑器中配置它们。我制作了 类 代表不同的行为类型和可以执行的操作。 有没有办法让我在为这些 类 输入的脚本上创建一个字段,以便我可以使用检查器拖放来配置不同的预制件?
下面是一些演示情况的代码:
Unit.cs
// A unit on the board.
public class Unit : MonoBehaviour
{
public UnitAction action;
}
UnitAction.cs
// A unit on the board.
public class UnitAction : MonoBehaviour
{
// Does things
}
将此脚本应用到预制件后,这些字段会显示在检查器中,但没有填充默认字段值的选项。如果我将字段类型设置为 UnityEngine.Object
,我可以将脚本放在那里,但这似乎是我不想要的。
我猜你不希望这些脚本暴露在编辑器之外,所以你可以使用一个名为 SerializeField
的属性。它会将字段公开给编辑器,以便您可以拖入引用,但其他脚本将无法访问您放入的字段。
如果你想让特定的脚本出现在编辑器中,只需写
[SerializeField] private YourScriptName scriptReference = null;
由于列表是通用结构,如果你愿意,你也可以用类似的方式制作脚本列表
[SerializeField] private List<YourScriptName> scriptListReference = new List<YourScriptName>();
因为我不认为你会再次分配这些引用,如果你想在任何时候获取引用,你可以制作一个 getter 方法。
public YourScriptName GetYourScript(){ return scriptReference;}
很少有Unity无法序列化的字段,所以一般来说,如果你想拖入对组件、脚本、对象等的引用,你需要做的就是让它成为SerializeField
或 public 后跟要拖入的任何类型。
来自文档,序列化系统
CANNOT serialize static fields.
CANNOT serialize properties.
CAN serialize public non-static fields (of serializable types)
CAN serialize nonpublic non-static fields marked with the SerializeField attribute.
它可以序列化的字段如下
- 所有 类 继承自 UnityEngine.Object,例如 游戏对象、组件、MonoBehaviour、Texture2D、AnimationClip。
- 所有基本数据类型,如 int、string、float、bool。
- 一些内置类型,例如 Vector2、Vector3、Vector4、Quaternion、Matrix4x4、Color、Rect、LayerMask。
- 可序列化类型的数组 a 的列表 可序列化类型
- 枚举
- 结构
听起来您正在尝试序列化对脚本本身的引用而不是那些脚本的实例。您可能希望通过多种方式执行此操作:
您可以将您的 UnitAction 脚本作为 GameObject 的组件附加到您的“Unit”对象可访问的上下文中(在同一场景中,“Unit”对象的子对象,或者 -可能是最常见的情况——“Unit”对象本身)。然后,您将能够将这些实例化组件序列化到您的 Unit class 中的字段中。这是最常见的用例。
您可以为每个 UnitAction 组件创建一个预制件,然后将这些预制件序列化到您的 Unit class 字段中。然后您将在运行时实例化一个 UnitAction。根据您的描述,这似乎并不适合您的情况,因为 UnitAction 可能不是需要动态实例化的东西,但了解这一点很重要。本文有一个使用此方法为单位提供法术列表的示例(并且还提供了一些关于如何考虑使用可能对您有价值的统一组件的良好背景):