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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 01:24:08