版本:Unity 6 (6000.0)
语言:英语
在运行时为对象添加功能
属性访问器

属性包

属性包是针对给定 .Net 对象类型的一组属性,您可以使用它们来访问和设置该类型对象的实例数据。

概念

针对给定类型的属性包是一个伴随对象,它支持基于该类型实例的高效数据遍历算法。默认情况下,Unity 使用反射来为类型生成属性包。这种反射方法提供便利,并且仅在尚未注册属性包时才按类型延迟执行一次。

为了提高性能,您可以通过用 [Unity.Properties.GeneratePropertyBag] 标记类型来选择代码生成。此外,要激活代码生成,您必须用 [assembly: Unity.Properties.GeneratePropertyBagsForAssembly] 标记程序集。代码生成的属性包在加载域时会自动注册。

在反射和代码生成这两种情况下,属性包都会为以下内容生成属性:

属性包不会为用 [DontCreateProperty] 标记的公有、私有或内部字段生成属性。

如果字段是只读的,或者属性只有获取器,则生成的属性是只读的。

您还可以使用 [Unity.Properties.CreateProperty(ReadOnly = true)] 使生成的属性变为只读。

使用序列化属性在属性包中创建属性以获得便利并不总是最佳方法。Unity 的序列化系统只能对字段和自动属性起作用,这使得有效地实现验证或传播更改变得很困难。

以下示例将 Unity 序列化系统与 Unity Properties 系统相结合。

using UnityEngine;
using Unity.Properties;

public class MyBehaviour : MonoBehaviour
{
    // Serializations go through the field, but we don't want to create a property for it.
    [SerializeField, DontCreateProperty] 
    private int m_Value;
    
    // For the property bag, use the property instead of the field. This ensures that
    // the value stays within the appropriate bounds.
    [CreateProperty] 
    public int value
    {
        get => m_Value;
        set => m_Value = value;
    }
    
    // This is a similar example, but for an auto-property.
    [field: SerializeField, DontCreateProperty]
    [CreateProperty]
    public float floatValue { get; set; }
}

与 Unity 序列化系统不同,属性包中的属性不符合带有 [SerializeField] 的值类型的条件。相反,结构类型被识别为值类型,而类类型被识别为引用类型。

在 Unity 序列化中,虽然支持多态性,但您必须使用 [SerializeReference] 属性来明确选择加入。否则,实例将被序列化为值类型。值得注意的是,UnityEngine.Object 类型是此规则的例外,因为它们会自动被序列化为引用类型。

性能注意事项

Unity Properties 使用 .Net 反射来创建强类型化的属性包和属性,这会在您第一次为给定容器类型请求属性包时引入性能开销。

当您通过反射为字段成员创建属性时,这些属性可能会在 IL2CPP一种 Unity 开发的脚本后端,可以在构建某些平台的项目时用作 Mono 的替代方案。更多信息
查看 词汇表
构建中分配垃圾。这种分配是由于直接使用 System.Reflection.FieldInfo 造成的,这会导致不可避免的装箱。

要避免反射,您可以在编译期间代码生成属性包。但是,请注意,这种优化可能会导致更长的编译时间。要为程序集启用代码生成,请用 [Unity.Properties.GeneratePropertyBagsForAssemblyAttribute] 标记程序集,并用 [Unity.Properties.GeneratePropertyBagAttribute] 标记单个类型。要使属性包能够访问内部和私有字段和属性,请将类型设为 partial

其他资源

在运行时为对象添加功能
属性访问器