Skip to content

Commit b04c4f2

Browse files
committed
- Fixed update condition.
- Added show obsolete members option. - Better error handling of getting value of properties. - Property values in components with "execute in edit mode" attribute will be auto fetched.
1 parent c6f953d commit b04c4f2

File tree

4 files changed

+179
-33
lines changed

4 files changed

+179
-33
lines changed

Assets/Script Tester/Editor/ComponentMethodDrawer.cs

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using UnityEngine;
22
using UnityEditor;
3+
using UnityEditor.AnimatedValues;
34
using System;
45
using System.Collections.Generic;
56
using System.Linq;
@@ -10,6 +11,9 @@ namespace ScriptTester {
1011
class ComponentMethodDrawer:IReflectorDrawer {
1112
UnityEngine.Object component;
1213
readonly List<ComponentMethod> methods = new List<ComponentMethod>();
14+
AnimBool showMethodOptions;
15+
AnimBool showMethodSelector;
16+
AnimBool showResultSelector;
1317
string[] methodNames;
1418
int selectedMethodIndex;
1519
MethodInfo selectedMethod;
@@ -58,11 +62,19 @@ public bool IsComponentNull() {
5862
}
5963

6064
public ComponentMethodDrawer() {
65+
showMethodSelector = new AnimBool(false);
66+
showMethodOptions = new AnimBool(false);
67+
showResultSelector = new AnimBool(false);
68+
showMethodSelector.valueChanged.AddListener(RequireRedraw);
69+
showMethodOptions.valueChanged.AddListener(RequireRedraw);
70+
showResultSelector.valueChanged.AddListener(RequireRedraw);
6171
}
6272

63-
public ComponentMethodDrawer(UnityEngine.Object target) {
73+
public ComponentMethodDrawer(UnityEngine.Object target)
74+
: this() {
6475
component = target;
6576
drawHeader = false;
77+
showMethodSelector.value = true;
6678
InitComponentMethods();
6779
}
6880

@@ -101,10 +113,21 @@ public void Draw() {
101113
EditorGUILayout.BeginVertical();
102114
component = EditorGUILayout.ObjectField("Target", component, typeof(UnityEngine.Object), true);
103115
}
104-
if(component != null)
116+
if(component != null) {
117+
if(GUI.changed) {
118+
InitComponentMethods();
119+
GUI.changed = false;
120+
}
121+
showMethodSelector.target = true;
122+
} else
123+
showMethodSelector.target = false;
124+
if(EditorGUILayout.BeginFadeGroup(showMethodSelector.faded))
105125
DrawComponent();
106-
if(result != null || thrownException != null)
126+
EditorGUILayout.EndFadeGroup();
127+
showResultSelector.target = result != null || thrownException != null;
128+
if(EditorGUILayout.BeginFadeGroup(showResultSelector.faded))
107129
DrawResult();
130+
EditorGUILayout.EndFadeGroup();
108131
if(drawHeader) {
109132
EditorGUILayout.EndVertical();
110133
EditorGUI.indentLevel--;
@@ -167,20 +190,21 @@ void InitMethodParams() {
167190
}
168191

169192
void DrawComponent() {
170-
if(GUI.changed) {
171-
InitComponentMethods();
172-
GUI.changed = false;
173-
}
174193
selectedMethodIndex = EditorGUILayout.Popup("Method", selectedMethodIndex, methodNames);
175-
if(selectedMethodIndex >= 0)
194+
if(selectedMethodIndex >= 0) {
195+
if(GUI.changed) {
196+
InitMethodParams();
197+
GUI.changed = false;
198+
}
199+
showMethodOptions.target = true;
200+
} else
201+
showMethodOptions.target = false;
202+
if(EditorGUILayout.BeginFadeGroup(showMethodOptions.faded))
176203
DrawMethod();
204+
EditorGUILayout.EndFadeGroup();
177205
}
178206

179207
void DrawMethod() {
180-
if(GUI.changed) {
181-
InitMethodParams();
182-
GUI.changed = false;
183-
}
184208
if(paramsFolded = EditorGUILayout.Foldout(paramsFolded, selectedMethod.Name)) {
185209
GUI.changed = false;
186210
EditorGUI.indentLevel++;

Assets/Script Tester/Editor/Helpers.cs

Lines changed: 89 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ class InspectorDrawer {
3333
public UnityEngine.Object target;
3434
public List<IReflectorDrawer> drawer;
3535
public bool shown;
36+
public bool isInternalType;
3637
public InspectorDrawer(UnityEngine.Object target) {
3738
this.target = target;
3839
this.drawer = new List<IReflectorDrawer>();
@@ -185,18 +186,102 @@ static StringBuilder JoinStringList(StringBuilder sb, IList<string> list, string
185186
return sb;
186187
}
187188

188-
internal static Quaternion QuaterionField(string label, Quaternion value, params GUILayoutOption[] options) {
189+
internal static Quaternion QuaternionField(string label, Quaternion value, params GUILayoutOption[] options) {
189190
var cValue = new Vector4(value.x, value.y, value.z, value.w);
190191
cValue = EditorGUILayout.Vector4Field(label, cValue, options);
191192
return new Quaternion(cValue.x, cValue.y, cValue.z, cValue.w);
192193
}
193194

194-
internal static Quaternion QuaterionField(Rect position, string label, Quaternion value) {
195+
internal static Quaternion QuaternionField(Rect position, string label, Quaternion value) {
195196
var cValue = new Vector4(value.x, value.y, value.z, value.w);
196197
cValue = EditorGUI.Vector4Field(position, label, cValue);
197198
return new Quaternion(cValue.x, cValue.y, cValue.z, cValue.w);
198199
}
199200

201+
internal static int EnumField(Rect position, string label, Type type, int value) {
202+
string[] itemNames;
203+
int[] itemValues;
204+
int val = EnumFieldPreProcess(type, value, out itemNames, out itemValues);
205+
int newVal = EditorGUI.Popup(position, label, val, itemNames);
206+
return EnumFieldPostProcess(itemValues, newVal);
207+
}
208+
209+
internal static int EnumField(string label, Type type, int value, params GUILayoutOption[] options) {
210+
string[] itemNames;
211+
int[] itemValues;
212+
int val = EnumFieldPreProcess(type, value, out itemNames, out itemValues);
213+
int newVal = EditorGUILayout.Popup(label, val, itemNames, options);
214+
return EnumFieldPostProcess(itemValues, newVal);
215+
}
216+
217+
static int EnumFieldPreProcess(Type type, int val, out string[] itemNames, out int[] itemValues) {
218+
itemNames = Enum.GetNames(type);
219+
itemValues = Enum.GetValues(type) as int[];
220+
for(int i = 0; i < itemValues.Length; i++)
221+
if(val == itemValues[i])
222+
return i;
223+
return 0;
224+
}
225+
226+
static int EnumFieldPostProcess(int[] itemValues, int val) {
227+
return itemValues[val];
228+
}
229+
230+
231+
internal static int MaskedEnumField(Rect position, string label, Type type, int mask) {
232+
return MaskedEnumField(position, new GUIContent(label), type, mask);
233+
}
234+
235+
internal static int MaskedEnumField(Rect position, GUIContent label, Type type, int mask) {
236+
string[] itemNames;
237+
int[] itemValues;
238+
int val = MaskedEnumFieldPreProcess(type, mask, out itemNames, out itemValues);
239+
int newVal = EditorGUI.MaskField(position, label, val, itemNames);
240+
return MaskedEnumFieldPostProcess(itemValues, mask, val, newVal);
241+
}
242+
243+
internal static int MaskedEnumField(string label, Type type, int mask, params GUILayoutOption[] options) {
244+
return MaskedEnumField(new GUIContent(label), type, mask, options);
245+
}
246+
247+
internal static int MaskedEnumField(GUIContent label, Type type, int mask, params GUILayoutOption[] options) {
248+
string[] itemNames;
249+
int[] itemValues;
250+
int val = MaskedEnumFieldPreProcess(type, mask, out itemNames, out itemValues);
251+
int newVal = EditorGUILayout.MaskField(label, val, itemNames, options);
252+
return MaskedEnumFieldPostProcess(itemValues, mask, val, newVal);
253+
}
254+
255+
static int MaskedEnumFieldPreProcess(Type type, int val, out string[] itemNames, out int[] itemValues) {
256+
itemNames = Enum.GetNames(type);
257+
itemValues = Enum.GetValues(type) as int[];
258+
int maskVal = 0;
259+
for(int i = 0; i < itemValues.Length; i++) {
260+
if(itemValues[i] != 0) {
261+
if((val & itemValues[i]) == itemValues[i])
262+
maskVal |= 1 << i;
263+
} else if(val == 0)
264+
maskVal |= 1 << i;
265+
}
266+
return maskVal;
267+
}
268+
269+
static int MaskedEnumFieldPostProcess(int[] itemValues, int val, int maskVal, int newMaskVal) {
270+
int changes = maskVal ^ newMaskVal;
271+
for(int i = 0; i < itemValues.Length; i++)
272+
if((changes & (1 << i)) != 0) {
273+
if((newMaskVal & (1 << i)) != 0) {
274+
if(itemValues[i] == 0) {
275+
val = 0;
276+
break;
277+
}
278+
val |= itemValues[i];
279+
} else
280+
val &= ~itemValues[i];
281+
}
282+
return val;
283+
}
284+
200285
internal static bool AssignValue(MemberInfo info, object target, object value) {
201286
try {
202287
var fieldInfo = info as FieldInfo;
@@ -224,7 +309,8 @@ internal static bool FetchValue(MemberInfo info, object target, out object value
224309
value = propertyInfo.GetValue(target, null);
225310
else
226311
return false;
227-
} catch {
312+
} catch(Exception ex) {
313+
value = ex;
228314
return false;
229315
}
230316
return true;

Assets/Script Tester/Editor/InspectorPlus.cs

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class InspectorPlus : EditorWindow {
1717
bool showProps = true;
1818
bool showMethods = true;
1919
bool locked = false;
20+
bool showObsolete = false;
2021
int[] instanceIds = new int[0];
2122

2223
void OnEnable() {
@@ -65,8 +66,11 @@ void OnGUI() {
6566
if(!Helper.AssignValue(item.Info, drawer.target, item.Value)) {
6667
object value;
6768
var propDrawer = item as MethodPropertyDrawer;
68-
if(propDrawer != null && Helper.FetchValue(propDrawer.Info, drawer.target, out value))
69+
if(propDrawer != null && Helper.FetchValue(propDrawer.Info, drawer.target, out value)) {
6970
propDrawer.Value = value;
71+
propDrawer.GetException = null;
72+
} else
73+
propDrawer.GetException = value as Exception;
7074
}
7175
}
7276
}
@@ -83,16 +87,12 @@ void ShowMenu() {
8387
var menu = new GenericMenu();
8488
menu.AddItem(new GUIContent("Update Values"), false, UpdateValues);
8589
menu.AddItem(new GUIContent("Reload All"), false, RefreshList);
90+
menu.AddSeparator("");
8691
menu.AddItem(new GUIContent("Lock Selection"), locked, () => {
8792
locked = !locked;
8893
if(!locked)
8994
OnSelectionChange();
9095
});
91-
menu.AddSeparator("");
92-
menu.AddItem(new GUIContent("Show Private Members"), privateFields, () => {
93-
privateFields = !privateFields;
94-
RefreshList();
95-
});
9696
menu.AddItem(new GUIContent("Update Properties in Edit Mode"), forceUpdateProps, () => {
9797
forceUpdateProps = !forceUpdateProps;
9898
UpdateValues();
@@ -106,6 +106,14 @@ void ShowMenu() {
106106
showMethods = !showMethods;
107107
RefreshList();
108108
});
109+
menu.AddItem(new GUIContent("Show Private Members"), privateFields, () => {
110+
privateFields = !privateFields;
111+
RefreshList();
112+
});
113+
menu.AddItem(new GUIContent("Show Obsolete Members"), showObsolete, () => {
114+
showObsolete = !showObsolete;
115+
RefreshList();
116+
});
109117
menu.DropDown(toolbarMenuPos);
110118
}
111119

@@ -127,6 +135,7 @@ void OnSelectionChange() {
127135
if (drawers.FindIndex(drawer => drawer[0].target.GetInstanceID() == instanceID) < 0)
128136
pendingAddDrawers.Add(CreateDrawers(instanceID));
129137
drawers.AddRange(pendingAddDrawers);
138+
UpdateValues();
130139
Repaint();
131140
}
132141

@@ -158,9 +167,10 @@ InspectorDrawer CreateDrawer(UnityEngine.Object target, bool shown) {
158167
var targetType = target.GetType();
159168
var fields = targetType.GetFields(flag);
160169
var props = !showProps ? null : targetType.GetProperties(flag).Where(prop => prop.GetIndexParameters().Length == 0).ToArray();
170+
drawer.isInternalType = !(target is MonoBehaviour) || Attribute.IsDefined(target.GetType(), typeof(ExecuteInEditMode));
161171
foreach (var field in fields)
162172
try {
163-
if (Attribute.IsDefined(field, typeof(ObsoleteAttribute)))
173+
if (!showObsolete && Attribute.IsDefined(field, typeof(ObsoleteAttribute)))
164174
continue;
165175
drawer.drawer.Add(new MethodPropertyDrawer(field.FieldType, Helper.GetMemberName(field, true), field.GetValue(target)) {
166176
AllowReferenceMode = false,
@@ -172,19 +182,19 @@ InspectorDrawer CreateDrawer(UnityEngine.Object target, bool shown) {
172182
if (showProps)
173183
foreach (var prop in props)
174184
try {
175-
if (Attribute.IsDefined(prop, typeof(ObsoleteAttribute)))
185+
if (!showObsolete && Attribute.IsDefined(prop, typeof(ObsoleteAttribute)))
176186
continue;
177187
drawer.drawer.Add(new MethodPropertyDrawer(prop.PropertyType, Helper.GetMemberName(prop, true), prop.CanRead && EditorApplication.isPlaying ? prop.GetValue(target, null) : null) {
178188
AllowReferenceMode = false,
179189
Info = prop,
180-
Updatable = Helper.GetState<bool>(prop, true),
181-
ShowUpdatable = true
190+
Updatable = drawer.isInternalType || Helper.GetState<bool>(prop, true),
191+
ShowUpdatable = !drawer.isInternalType
182192
});
183193
} catch (Exception ex) {
184194
Debug.LogException(ex);
185195
}
186196
if (showMethods)
187-
drawer.drawer.Add(new ComponentMethodDrawer(target) { ShouldDrawHeader = false });
197+
drawer.drawer.Add(new ComponentMethodDrawer(target));
188198
foreach (var d in drawer.drawer)
189199
d.OnRequireRedraw += Repaint;
190200
drawer.shown = shown;
@@ -203,11 +213,14 @@ void UpdateValues(bool updateProps) {
203213
if (propDrawer == null)
204214
continue;
205215
var isPropInfo = propDrawer.Info is PropertyInfo;
206-
if ((!updateProps || !propDrawer.Updatable) && isPropInfo)
216+
if (!drawer.isInternalType && (!updateProps || !propDrawer.Updatable) && isPropInfo)
207217
continue;
208218
object value;
209-
if (Helper.FetchValue(propDrawer.Info, drawer.target, out value))
219+
if(Helper.FetchValue(propDrawer.Info, drawer.target, out value)) {
210220
propDrawer.Value = value;
221+
propDrawer.GetException = null;
222+
} else
223+
propDrawer.GetException = value as Exception;
211224
}
212225
}
213226
}

0 commit comments

Comments
 (0)