public static Dictionary <string, bool> GetEnableDict(object target) { Type type = target.GetType(); FieldInfo[] fields = type.GetFields(); Dictionary <string, bool> enableDict = new Dictionary <string, bool>(); foreach (var field in fields) { EnableToggleAttribute attr = field.GetCustomAttribute <EnableToggleAttribute>(); if (attr == null) { continue; } object obj = field.GetValue(target); if (obj == null) { continue; } enableDict[field.Name] = obj.ConvertTo(false); } return(enableDict); }
public static object DrawObject(GUIContent title, object obj, Type type, object[] attrs = null) { using (var lay = new EditorGUILayout.VerticalScope()) { if (null == obj) {//初始化 obj = TypeUtility.CreateInstance(type); } float oldLabelWidth = EditorGUIUtility.labelWidth; EditorGUIUtility.labelWidth = CalcLabelWidth(title); obj = DrawObjectCustom(out bool isDraw, title, obj, type, attrs); if (!isDraw) { switch (obj) { case float v: { RangeAttribute attr = GetTargetAttr <RangeAttribute>(); obj = null == attr?EditorGUILayout.FloatField(title, v) : EditorGUILayout.Slider(title, v, attr.min, attr.max); } break; case double v: obj = EditorGUILayout.DoubleField(title, v); break; case int v: { RangeAttribute attr = GetTargetAttr <RangeAttribute>(); obj = null == attr?EditorGUILayout.IntField(title, v) : EditorGUILayout.IntSlider(title, v, (int)attr.min, (int)attr.max); } break; case string v: obj = EditorGUILayout.TextField(title, v); break; case bool v: obj = EditorGUILayout.Toggle(title, v); break; case Vector2 v: { v = EditorGUILayout.Vector2Field(title, v); RangeAttribute attr = GetTargetAttr <RangeAttribute>(); if (attr != null) { v.x = Mathf.Clamp(v.x, attr.min, attr.max); v.y = Mathf.Clamp(v.y, attr.min, attr.max); if (v.x > v.y) { v.x = v.y; } using (var lay2 = new EditorGUILayout.HorizontalScope()) { GUILayout.Space(EditorGUIUtility.labelWidth); EditorGUILayout.MinMaxSlider(ref v.x, ref v.y, attr.min, attr.max); } } obj = v; } break; case Vector3 v: obj = EditorGUILayout.Vector3Field(title, v); break; case Vector2Int v: { v = EditorGUILayout.Vector2IntField(title, v); RangeAttribute attr = GetTargetAttr <RangeAttribute>(); if (attr != null) { Vector2 vf = v; v.x = Mathf.Clamp(Mathf.RoundToInt(vf.x), (int)attr.min, (int)attr.max); v.y = Mathf.Clamp(Mathf.RoundToInt(vf.y), (int)attr.min, (int)attr.max); if (v.x > v.y) { v.x = v.y; } using (var lay2 = new EditorGUILayout.HorizontalScope()) { GUILayout.Space(EditorGUIUtility.labelWidth); EditorGUILayout.MinMaxSlider(ref vf.x, ref vf.y, attr.min, attr.max); } v = new Vector2Int((int)vf.x, (int)vf.y); } obj = v; } break; case Vector3Int v: obj = EditorGUILayout.Vector3IntField(title, v); break; case Enum v: { FlagsAttribute attr = GetTargetAttr <FlagsAttribute>(); obj = null == attr?EditorGUILayout.EnumPopup(title, v) : EditorGUILayout.EnumFlagsField(title, v); } break; case LayerMask v: { int mask = InternalEditorUtility.LayerMaskToConcatenatedLayersMask(v); mask = EditorGUILayout.MaskField(title, mask, InternalEditorUtility.layers); obj = InternalEditorUtility.ConcatenatedLayersMaskToLayerMask(mask); } break; case IList v: { if (type.IsGenericType && type.GenericTypeArguments.Length == 1) { Type subType = type.GenericTypeArguments[0]; using (var lay2 = new EditorGUILayout.VerticalScope("FrameBox")) { if (subType.IsClass || subType.IsValueType) { EditorGUIUtility.labelWidth = CalcLabelWidth(title); EditorGUILayout.BeginHorizontal(); int cnt = EditorGUILayout.IntField(title, v.Count); if (GUILayout.Button("+", GUILayout.Width(40))) { cnt++; GUI.FocusControl(null); } EditorGUILayout.EndHorizontal(); EditorGUIUtility.labelWidth = oldLabelWidth; int diff = cnt - v.Count; while (diff < 0) { v.RemoveAt(v.Count - 1); diff++; } while (diff > 0) { object subObj = TypeUtility.CreateInstance(subType); v.Add(subObj); diff--; } EditorGUI.indentLevel += 1; for (int i = 0; i < cnt; i++) { using (var lay3 = new EditorGUILayout.VerticalScope("FrameBox")) { v[i] = DrawObject(new GUIContent($"{i}"), v[i], subType, attrs); using (var lay4 = new EditorGUILayout.HorizontalScope()) { if (GUILayout.Button("↑") && i > 0) { object swap = v[i - 1]; v[i - 1] = v[i]; v[i] = swap; } if (GUILayout.Button("↓") && i < cnt - 1) { object swap = v[i + 1]; v[i + 1] = v[i]; v[i] = swap; } if (GUILayout.Button("x")) { v.RemoveAt(i); i--; cnt--; } } } } EditorGUI.indentLevel -= 1; } } } else { EditorGUILayout.LabelField($"不支持 {type} 类型"); } obj = v; } break; default: { if (!type.IsPrimitive && (type.IsClass || type.IsValueType)) { FieldInfo[] fields = type.GetFields(); //============================================================= //查找成员显示控制 Dictionary <string, bool> enableDict = EnableToggleAttribute.GetEnableDict(obj); //============================================================= int depth = 0; if (title != GUIContent.none) { EditorGUILayout.LabelField($"{title.text}"); depth = 1; } EditorGUI.indentLevel += depth; foreach (var field in fields) { //============================================================= if (!EnableToggleItemAttribute.EnableChecker(field, enableDict)) { //不显示 continue; } //=========================================================== DrawField(obj, field); } EditorGUI.indentLevel -= depth; } else { EditorGUILayout.LabelField($"不支持 {type} 类型"); } } break; } } EditorGUIUtility.labelWidth = oldLabelWidth; return(obj); T GetTargetAttr <T>() where T : Attribute { T result = null; if (attrs != null) { result = (T)Array.Find(attrs, t => t is T); } if (result == null) { result = type.GetCustomAttribute <T>(); } return(result); } } }