11using System ;
2- using System . Collections . Generic ;
3- using Unity . Properties ;
2+ using System . Collections ;
3+ using System . Reflection ;
44using UnityEditor ;
55using 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