【问题标题】:How to get a value from an array of scriptable objects in unity custom editor?如何从统一自定义编辑器中的可编写脚本对象数组中获取值?
【发布时间】:2021-12-26 01:05:06
【问题描述】:

我正在尝试制作自定义编辑器,但无法从数组中的可编写脚本的对象中获取值。 这是包含 CharacterData 可脚本化对象的 FightData 脚本。

public class FightData : ScriptableObject {
    public CharacterData [] enemyDatas;
}

CharacterData 包含统计数据。

public class CharacterData : ScriptableObject {

    public CharacterStats stats;
}

这里是 CharacterStats

[System.Serializable]
public class CharacterStats
{
    public float HP;
    public float damage;
    public float defense;
    public float attackInterval;

    public CharacterStats(){
        HP = 0f;
        damage = 0f;
        defense = 0f;
        attackInterval = 2f;
    }
}

我想总结所有统计数据并将它们显示在 FightData 的自定义编辑器中。但统计数据始终为空。 这是我的方法:

[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++)
        {
            SerializedProperty stats = _enemyDatas.GetArrayElementAtIndex(i).serializedObject.FindProperty("stats");
            if(stats == null){
                Debug.Log(stats);
                continue;
            }
            result += stats.FindPropertyRelative("HP").floatValue;
            result += stats.FindPropertyRelative("damage").floatValue;
            result += stats.FindPropertyRelative("defense").floatValue;
        }

        EditorGUILayout.Space(); 
        EditorGUILayout.LabelField("Total Power", EditorStyles.boldLabel);
        EditorGUILayout.FloatField(result);

 
        serializedObject.ApplyModifiedProperties();
    }
}

【问题讨论】:

    标签: c# unity3d unity-editor unity3d-editor scriptable-object


    【解决方案1】:

    FindPropertyRelative 仅在它实际上是一个嵌套的“普通”序列化类并序列化为 YAML 值时才有效。

    但是对于ScriptableObject(通常是从UnityEngine.Object 继承的任何东西),您存储的不是序列化的,而只是UnityEngine.Object 引用

    您需要获取相应的SerializedObject 实例,例如

    [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++)
            {
                // Get the element SerializedProperty
                var element = _enemyDatas.GetArrayElementAtIndex(i);
    
                // The field exists but no object is referenced
                if(!element.objectReferenceValue)
                {
                    continue;
                }
    
                // otherwise get a serialized object for this reference
                var sObj = new SerializedObject(element.objectReferenceValue);
    
                // stats is now a property of that serialized object
                var stats = sObj.FindProperty("stats");
    
                // The other values are now further nested properties of the serialized CharacterStats class
                result += stats.FindPropertyRelative("HP").floatValue;
                result += stats.FindPropertyRelative("damage").floatValue;
                result += stats.FindPropertyRelative("defense").floatValue;
            }
    
            EditorGUILayout.Space(); 
            EditorGUILayout.LabelField("Total Power", EditorStyles.boldLabel);
            EditorGUILayout.FloatField(result);
    
     
            serializedObject.ApplyModifiedProperties();
        }
    }
    

    注意:如果您要公开这些 SerializedObjects 的字段并且还想更改它们,您还需要相应地调用

    sObj.Update();
    
    ...
    
    sObj.ApplyModifiedProperties();
    

    在智能手机上输入,但我希望思路清晰

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-25
      • 2012-12-31
      相关资源
      最近更新 更多