Skip to content

Commit e5029cb

Browse files
committed
Drawer support nested field
1 parent 631b27b commit e5029cb

File tree

1 file changed

+54
-26
lines changed

1 file changed

+54
-26
lines changed
Lines changed: 54 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using System;
2-
using System.Collections.Generic;
3-
using Unity.Properties;
2+
using System.Collections;
3+
using System.Reflection;
44
using UnityEditor;
55
using UnityEngine;
66

@@ -17,47 +17,75 @@ public override void OnGUI(Rect position, SerializedProperty property, GUIConten
1717
GUI.enabled = Application.isPlaying;
1818
if (GUI.Button(position, "View Tree"))
1919
{
20-
object value = fieldInfo.GetValue(property.serializedObject.targetObject);
20+
object value = GetTargetObjectOfProperty(property);
2121
if (value is IBehaviorTree tree)
2222
{
2323
BehaviorTreeWindow.ShowTree(tree, tree.Name ?? property.displayName);
2424
}
25-
else if (value is IList<BehaviorTree> list)
25+
else
2626
{
27-
if (TryGetArrayIndex(property.propertyPath, out int index) && list[index] is IBehaviorTree childTree)
28-
{
29-
BehaviorTreeWindow.ShowTree(childTree, childTree.Name ?? property.displayName);
30-
}
27+
Debug.LogWarning($"BehaviorTreeDrawer: cannot resolve runtime value for property '{property.propertyPath}'.");
3128
}
3229
}
3330
GUI.enabled = true;
3431

3532
EditorGUI.EndProperty();
3633
}
37-
private bool TryGetArrayIndex(string path, out int index)
34+
public object GetTargetObjectOfProperty(SerializedProperty prop)
3835
{
39-
const string arrayData = ".Array.data[";
40-
int arrayIndex = path.IndexOf(arrayData, StringComparison.Ordinal);
41-
if (arrayIndex < 0)
42-
{
43-
index = -1;
44-
return false;
45-
}
36+
if (prop == null) return null;
37+
38+
object obj = prop.serializedObject.targetObject;
39+
if (obj == null) return null;
40+
41+
string path = prop.propertyPath.Replace(".Array.data[", "[");
42+
string[] elements = path.Split('.');
4643

47-
arrayIndex += arrayData.Length;
48-
int endIndex = path.IndexOf("]", arrayIndex, StringComparison.Ordinal);
49-
if (endIndex < 0)
44+
foreach (string element in elements)
5045
{
51-
index = -1;
52-
return false;
46+
if (element.Contains("["))
47+
{
48+
int indexStart = element.IndexOf("[", StringComparison.Ordinal);
49+
string memberName = element.Substring(0, indexStart);
50+
string indexStr = element.Substring(indexStart)
51+
.Trim('[', ']');
52+
53+
obj = GetMemberValue(obj, memberName);
54+
55+
if (obj is IList list && int.TryParse(indexStr, out int index) && index >= 0 && index < list.Count)
56+
{
57+
obj = list[index];
58+
}
59+
else
60+
{
61+
return null;
62+
}
63+
}
64+
else
65+
{
66+
obj = GetMemberValue(obj, element);
67+
}
68+
69+
if (obj == null)
70+
return null;
5371
}
5472

55-
string indexStr = path.Substring(arrayIndex, endIndex - arrayIndex);
56-
if (int.TryParse(indexStr, out index))
57-
return true;
73+
return obj;
74+
}
75+
76+
private object GetMemberValue(object source, string name)
77+
{
78+
if (source == null)
79+
return null;
80+
var type = source.GetType();
81+
82+
const BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
83+
84+
FieldInfo field = type.GetField(name, flags);
85+
if (field != null)
86+
return field.GetValue(source);
5887

59-
index = -1;
60-
return false;
88+
return null;
6189
}
6290
}
6391
}

0 commit comments

Comments
 (0)