1
- using System . Reflection ;
1
+ using System . Collections ;
2
+ using System . Collections . Generic ;
3
+ using System . Reflection ;
4
+ using System . Linq ;
2
5
using UnityEditor ;
3
6
4
7
namespace Lachee . Utilities . Editor
@@ -23,17 +26,71 @@ public static System.Type GetSerializedType(this SerializedProperty property)
23
26
/// <returns></returns>
24
27
public static FieldInfo GetSerializedFieldInfo ( this SerializedProperty property )
25
28
{
26
- BindingFlags flag = BindingFlags . Instance | BindingFlags . Public | BindingFlags . NonPublic | BindingFlags . GetField ;
27
29
System . Type parentType = property . serializedObject . targetObject . GetType ( ) ;
28
- return parentType . GetFieldInfoFromPath ( property . propertyPath , flag ) ;
30
+ return parentType . GetFieldInfoFromPath ( property . propertyPath ) ;
29
31
}
30
32
31
33
/// <summary>
32
- /// Gets the field info from the given property path
34
+ /// Gets the underlying value this property represents
35
+ /// </summary>
36
+ /// <param name="property"></param>
37
+ /// <returns></returns>
38
+ public static object GetSerializedValue ( this SerializedProperty property )
39
+ {
40
+ #if ! DISABLE_FAST_SERIALIZED_VALUE_LOOKUP
41
+ switch ( property . propertyType )
42
+ {
43
+ default : // If we cant find anything, we should just use the raw .ToString of the value
44
+ case SerializedPropertyType . Enum : // Its easier to just lookup the enum properties than recreating it
45
+ break ;
46
+
47
+ // Manually get a bunch because its more efficient than looking up serialized values
48
+ case SerializedPropertyType . ObjectReference :
49
+ return property . objectReferenceValue ? property . objectReferenceValue . name : "[ NULL ]" ;
50
+ case SerializedPropertyType . Boolean :
51
+ return property . boolValue ;
52
+ case SerializedPropertyType . Integer :
53
+ return property . intValue ;
54
+ case SerializedPropertyType . Float :
55
+ return property . floatValue ;
56
+ case SerializedPropertyType . String :
57
+ return property . stringValue ;
58
+ case SerializedPropertyType . Color :
59
+ return property . colorValue ;
60
+ case SerializedPropertyType . Vector2 :
61
+ return property . vector2Value ;
62
+ case SerializedPropertyType . Vector3 :
63
+ return property . vector3Value ;
64
+ case SerializedPropertyType . Vector4 :
65
+ return property . vector4Value ;
66
+ case SerializedPropertyType . Vector2Int :
67
+ return property . vector2IntValue ;
68
+ case SerializedPropertyType . Vector3Int :
69
+ return property . vector3IntValue ;
70
+ case SerializedPropertyType . Quaternion :
71
+ return property . quaternionValue ;
72
+ case SerializedPropertyType . Bounds :
73
+ return property . boundsValue ;
74
+ case SerializedPropertyType . BoundsInt :
75
+ return property . boundsIntValue ;
76
+ case SerializedPropertyType . Rect :
77
+ return property . rectValue ;
78
+ case SerializedPropertyType . RectInt :
79
+ return property . rectIntValue ;
80
+ }
81
+ #endif
82
+ // Lookup the property path and pull teh value directly
83
+ System . Type parentType = property . serializedObject . targetObject . GetType ( ) ;
84
+ return parentType . GetValueFromPath ( property . serializedObject . targetObject , property . propertyPath ) ;
85
+ }
86
+
87
+ /// <summary>
88
+ /// Finds the field info for the given type at the given path.
33
89
/// </summary>
34
90
/// <param name="type"></param>
35
91
/// <param name="path"></param>
36
92
/// <param name="flag"></param>
93
+ /// <remarks>Does not work with arrays yet as they would return a PropertyInfo instead</remarks>
37
94
/// <returns></returns>
38
95
public static FieldInfo GetFieldInfoFromPath ( this System . Type type , string path , BindingFlags flag = BindingFlags . Instance | BindingFlags . Public | BindingFlags . NonPublic | BindingFlags . GetField )
39
96
{
@@ -56,58 +113,85 @@ public static FieldInfo GetFieldInfoFromPath(this System.Type type, string path,
56
113
}
57
114
58
115
/// <summary>
59
- /// Gets the raw value of the property
116
+ /// Gets the field values from the given path
60
117
/// </summary>
61
- /// <param name="property"></param>
118
+ /// <param name="type">The type of the root object</param>
119
+ /// <param name="context">The root object to get the value from</param>
120
+ /// <param name="path">The SerializedProperty formatted path</param>
121
+ /// <param name="flag">The flag used to search fields.</param>
62
122
/// <returns></returns>
63
- #if CSHARP_7_3_OR_NEWER && ENABLE_DYNAMIC
64
- public static dynamic GetSerializedValue ( this SerializedProperty property ) {
65
- dynamic result ;
66
- #else
67
- public static object GetSerializedValue ( this SerializedProperty property ) {
68
- object result ;
69
- #endif
70
- BindingFlags flag = BindingFlags . Instance | BindingFlags . Public | BindingFlags . NonPublic | BindingFlags . GetField ;
71
- result = property . serializedObject . targetObject ;
72
- System . Type parentType = property . serializedObject . targetObject . GetType ( ) ;
123
+ public static object GetValueFromPath ( this System . Type type , object context , string path , BindingFlags flag = BindingFlags . Instance | BindingFlags . Public | BindingFlags . NonPublic | BindingFlags . GetField )
124
+ {
125
+ object result = context ;
126
+ System . Type resultType = type ;
73
127
74
- // See if we can return the object directly
75
- string path = property . propertyPath ;
76
- FieldInfo fi = null ; // = parentType.GetField(path, flag);
77
-
78
128
// We need to delve deeper until we hit the final result.
79
- string [ ] perDot = path . Split ( '.' ) ;
80
- foreach ( string fieldName in perDot )
129
+ string [ ] segments = path . Split ( '.' ) ;
130
+ for ( int i = 0 ; i < segments . Length ; i ++ )
81
131
{
82
- fi = parentType . GetField ( fieldName , flag ) ;
83
- if ( fi != null )
132
+ // If the field name is an array we need to break apart the next segment to extract its index.
133
+ // Once we have the index we can then use the `this` property arrays have to get the appropriate item and
134
+ // continue our search through the list of paths.
135
+ string fieldName = segments [ i ] ;
136
+ if ( fieldName == "Array" )
84
137
{
85
- parentType = fi . FieldType ;
86
- result = fi . GetValue ( result ) ;
138
+ // parse the index
139
+ string arrIndexPath = segments [ ++ i ] ;
140
+ string arrIndexStr = arrIndexPath . Substring ( 5 , arrIndexPath . Length - 1 - 5 ) ;
141
+ int arrIndex = int . Parse ( arrIndexStr ) ;
142
+
143
+ // get the property
144
+ var thisProperty = resultType . GetProperty ( "Item" , new System . Type [ ] { arrIndex . GetType ( ) } ) ;
145
+ var thisGetter = thisProperty . GetMethod ;
146
+
147
+ // Update the current state
148
+ result = thisGetter . Invoke ( result , new object [ ] { arrIndex } ) ;
149
+ resultType = result . GetType ( ) ;
87
150
}
88
151
else
89
152
{
90
- return null ;
153
+ var fi = resultType . GetField ( fieldName , flag ) ;
154
+ if ( fi == null ) return null ;
155
+
156
+ resultType = fi . FieldType ;
157
+ result = fi . GetValue ( result ) ;
91
158
}
92
159
}
93
160
94
161
return result ;
95
162
}
96
163
164
+
97
165
/// <summary>
98
166
/// Determines the best name for the given property
99
167
/// </summary>
100
168
/// <param name="property"></param>
101
169
/// <returns></returns>
102
170
public static string GetReadableName ( this SerializedProperty property )
103
171
{
104
- switch ( property . propertyType )
172
+ switch ( property . propertyType )
105
173
{
106
174
default :
107
175
return property . displayName ;
108
176
case SerializedPropertyType . ObjectReference :
109
177
return property . objectReferenceValue ? property . objectReferenceValue . name : "[ NULL ]" ;
110
178
}
111
179
}
180
+
181
+ /// <summary>
182
+ /// Gets the value of the property as a string
183
+ /// </summary>
184
+ /// <param name="property"></param>
185
+ /// <returns></returns>
186
+ public static string GetValueName ( this SerializedProperty property )
187
+ {
188
+ object value = property . GetSerializedValue ( ) ;
189
+ if ( value == null ) return "[ NULL ]" ;
190
+
191
+ if ( value is float vFloat )
192
+ return vFloat . ToString ( "n3" ) ;
193
+
194
+ return value . ToString ( ) ;
195
+ }
112
196
}
113
197
}
0 commit comments