如何从统一自定义编辑器中的可编写脚本的对象数组中获取值?
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 的自定义编辑器中。但统计数据始终为空。
这是我的方法:
[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
仅当它实际上是一个嵌套的“正常”序列化 class 时才有效,它被序列化为 YAML 值。
但是 for ScriptableObject
(一般来说任何继承自UnityEngine.Object
)你存储的东西没有被序列化values 而只是 UnityEngine.Object
reference!
您更需要获取相应的 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();
在智能手机上打字,但我希望思路清晰
我正在尝试创建一个自定义编辑器,但我无法从数组中的可编写脚本的对象中获取值。 这是包含 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();
}
}
FindPropertyRelative
仅当它实际上是一个嵌套的“正常”序列化 class 时才有效,它被序列化为 YAML 值。
但是 for ScriptableObject
(一般来说任何继承自UnityEngine.Object
)你存储的东西没有被序列化values 而只是 UnityEngine.Object
reference!
您更需要获取相应的 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();
在智能手机上打字,但我希望思路清晰