如何从统一自定义编辑器中的可编写脚本对象数组中获取值?
Posted
技术标签:
【中文标题】如何从统一自定义编辑器中的可编写脚本对象数组中获取值?【英文标题】: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();
【问题讨论】:
【参考方案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();
在智能手机上输入,但我希望思路清晰
【讨论】:
以上是关于如何从统一自定义编辑器中的可编写脚本对象数组中获取值?的主要内容,如果未能解决你的问题,请参考以下文章
为啥我在 Android 上运行之间会丢失可编写脚本对象中的数据,但在编辑器中却没有?