You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中serializedObject.FindProperty返回null,无法显示QuestSO属性

问题原因

你使用了C#的自动属性(带get;set;的属性)并添加了[field: SerializeField]标记,Unity序列化系统实际处理的是编译器自动生成的后备字段,而非你定义的属性名"a"或"listt"。这些后备字段的命名格式为<属性名>k__BackingField,因此直接用原属性名调用FindProperty会返回null。

解决方法

以下是三种可靠的处理方案:

方式一:改用普通序列化字段(推荐)

将自动属性改为普通字段,直接用[SerializeField]标记,这样字段名与序列化后的名称完全一致,可直接通过原名称查找属性:

[System.Serializable]
public class QuestSO : ScriptableObject
{
    [SerializeField] private List<int> _listt = new List<int> { 69, 420, 123, 2345 };
    [SerializeField] private int _a = 3;

    // 如需对外暴露数据,可添加只读属性
    public List<int> Listt => _listt;
    public int A => _a;
}

对应的Editor代码可直接使用修改后的字段名查找:

private void OnEnable()
{
    Debug.Log("OnEnable");
    
    _questSo = (QuestSO)target;
    SerializedObject serializedObject = new SerializedObject(_questSo);

    SerializedProperty aProperty = serializedObject.FindProperty("_a");
    SerializedProperty listProperty = serializedObject.FindProperty("_listt");
}

方式二:使用自动属性的后备字段名查找(不推荐,依赖编译器实现)

若坚持使用自动属性,可直接使用编译器生成的后备字段名查找,但该命名格式可能随C#版本变化,兼容性较差:

private void OnEnable()
{
    Debug.Log("OnEnable");
    
    _questSo = (QuestSO)target;
    SerializedObject serializedObject = new SerializedObject(_questSo);

    // 后备字段命名格式:<属性名>k__BackingField
    SerializedProperty aProperty = serializedObject.FindProperty("<a>k__BackingField");
    SerializedProperty listProperty = serializedObject.FindProperty("<listt>k__BackingField");

    if(aProperty != null){
        Debug.Log("a found");
    }
    if(listProperty != null){
        Debug.Log("list found");
    }
}

方式三:遍历所有序列化属性(通用)

若不确定字段名,可遍历SerializedObject的所有属性来定位目标:

private void OnEnable()
{
    Debug.Log("OnEnable");
    
    _questSo = (QuestSO)target;
    SerializedObject serializedObject = new SerializedObject(_questSo);

    SerializedProperty property = serializedObject.GetIterator();
    while (property.NextVisible(true))
    {
        Debug.Log($"Found property: {property.name}");
        // 匹配目标属性后进行处理
        if (property.name.EndsWith("a>k__BackingField"))
        {
            // 处理a属性
        }
        else if (property.name.EndsWith("listt>k__BackingField"))
        {
            // 处理listt属性
        }
    }
}
在Inspector中显示属性

获取到SerializedProperty后,在OnInspectorGUI方法中调用EditorGUILayout.PropertyField即可在Inspector中展示属性:

public override void OnInspectorGUI()
{
    serializedObject.Update();
    
    EditorGUILayout.PropertyField(aProperty);
    EditorGUILayout.PropertyField(listProperty);
    
    serializedObject.ApplyModifiedProperties();
}

内容的提问来源于stack exchange,提问作者mawerty

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 07:43:23