示例#1
0
        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);
                }
            }
        }