簡體   English   中英

如何從統一自定義編輯器中的一組可編寫腳本的對象中獲取值?

[英]How to get a value from an array of scriptable objects in unity custom editor?

我正在嘗試制作自定義編輯器,但無法從數組中的可編寫腳本的對象中獲取值。 這是包含 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 的自定義編輯器中。 但 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++)
        {
            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();
    }
}

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();

在智能手機上打字,但我希望這個想法變得清晰

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM