[Unity] SerializeField 和 ReadOnly 标签最好不要一起用,这样不方便在监视器中修改

375 阅读1分钟

ReadOnlyAttribute

我的 ReadOnlyAttribute 是抄网上的

结构如图:

图片.png

ReadOnlyAttribute.cs

using UnityEngine;

public class ReadOnlyAttribute : PropertyAttribute
{
 
}

ReadOnlyDrawer.cs

using UnityEditor;
using UnityEngine;

[CustomPropertyDrawer(typeof(ReadOnlyAttribute))]
public class ReadOnlyDrawer : PropertyDrawer
{
    public override float GetPropertyHeight(SerializedProperty property,
        GUIContent label)
    {
        return EditorGUI.GetPropertyHeight(property, label, true);
    }
 
    public override void OnGUI(Rect position,
        SerializedProperty property,
        GUIContent label)
    {
        GUI.enabled = false;
        EditorGUI.PropertyField(position, property, label, true);
        GUI.enabled = true;
    }
}

SerializeField 和 ReadOnly 标签最好不要一起用

假设你要把一个私有变量在监视器中显示,那么 SerializeField 和 ReadOnly 标签最好不要一起用

[SerializeField, ReadOnly]
private int food = 0;

public int Food
{
    get => food;
    set
    {
        food = value;
        OnFoodChanged?.Invoke(value);
    }
}

因为监视器会保存你最后一次修改这个私有变量的值

例如你之前写的代码是这样的,然后你再把私有变量的值改成其他值

[SerializeField, ReadOnly]
private int food = 10;

public int Food
{
    get => food;
    set
    {
        food = value;
        OnFoodChanged?.Invoke(value);
    }
}

那么这个时候监视器里依然保存的是 0 而不是你新改的 10

这个时候因为你的 ReadOnly 你还不能在监视器中把 10 改回来

也就是说一个私有变量使用 SerializeField 标签之后,也就是序列化之后,再次读取 Unity 时序列化的变量是有值的,不需要你再次去赋值,因为它已经被保存下来

这个时候如果用了 ReadOnly 就会阻止你修改这个被 Unity 保存的值

有的时候就会出 bug,让你以为你用的是修改后的值,实际上 Unity 保存的还是修改前的值,然后你又不能改 Unity 这个保存的值