Unity自定义编辑器中如何从ScriptableObject数组正确获取属性值
问题根因
错误出现在遍历数组读取stats属性的代码行:
SerializedProperty stats = _enemyDatas.GetArrayElementAtIndex(i).serializedObject.FindProperty("stats");
_enemyDatas.GetArrayElementAtIndex(i).serializedObject指向的仍然是当前FightData的序列化对象,而非数组元素引用的CharacterData实例对应的序列化对象,因此无法找到目标stats属性。
解决方法
推荐直接通过序列化属性的对象引用读取数值,实现更简单:
[CustomEditor(typeof(FightData))] public class FightDataEditor : Editor { SerializedProperty _enemyDatas; private void OnEnable() { _enemyDatas = serializedObject.FindProperty("enemyDatas"); } public override void OnInspectorGUI(){ serializedObject.Update(); EditorGUILayout.PropertyField(_enemyDatas); var result = 0f; int length = _enemyDatas.arraySize; for (int i = 0; i < length; i++) { // 拿到数组元素对应的CharacterData实例 SerializedProperty enemyProp = _enemyDatas.GetArrayElementAtIndex(i); CharacterData enemyData = enemyProp.objectReferenceValue as CharacterData; // 判空避免报错 if(enemyData == null || enemyData.stats == null){ continue; } result += enemyData.stats.HP; result += enemyData.stats.damage; result += enemyData.stats.defense; } EditorGUILayout.Space(); EditorGUILayout.LabelField("Total Power", EditorStyles.boldLabel); EditorGUILayout.FloatField(result); serializedObject.ApplyModifiedProperties(); } }
如果需要严格使用SerializedProperty方式读取,可修改遍历逻辑如下:
for (int i = 0; i < length; i++) { SerializedProperty enemyProp = _enemyDatas.GetArrayElementAtIndex(i); if(enemyProp.objectReferenceValue == null) continue; // 为CharacterData实例创建独立的SerializedObject SerializedObject enemySO = new SerializedObject(enemyProp.objectReferenceValue); SerializedProperty stats = enemySO.FindProperty("stats"); if(stats == null) continue; result += stats.FindPropertyRelative("HP").floatValue; result += stats.FindPropertyRelative("damage").floatValue; result += stats.FindPropertyRelative("defense").floatValue; }
额外注意事项
- 确保FightData的
enemyDatas数组内所有元素都已赋值非空的CharacterData实例 - 确保CharacterData实例中的
stats字段已完成初始化,未出现空值
内容的提问来源于stack exchange,提问作者genper
相关产品推荐
相关产品推荐

