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
相关产品推荐
相关产品推荐

