using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEditor; using System; using UnityEditor.SceneManagement; using System.Reflection; using UObject = UnityEngine.Object; using UnityEngine.UIElements; namespace TModule.Editor { [CustomEditor(typeof(UObject),true)] public class ObjectInspector : UnityEditor.Editor { BindingFlags flags = BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; List methodDrawers = new List(); List propertyInfos = new List(); List propertyDrawers = new List(); Dictionary methodDrawerTypes = new Dictionary(); Dictionary propertyDrawerTypes = new Dictionary(); private void OnEnable() { foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { foreach (var type in assembly.GetTypes()) { if (type.IsDefined(typeof(CustomMethodDrawerAttribute), true)) { Type type1 = type.GetCustomAttribute().AttributeType; if (methodDrawerTypes.ContainsKey(type1)) methodDrawerTypes[type1] = type; else methodDrawerTypes.Add(type1, type); } if (type.IsDefined(typeof(TCustomPropertyDrawerAttribute), true)) { Type type1 = type.GetCustomAttribute().AttributeType; if (propertyDrawerTypes.ContainsKey(type1)) propertyDrawerTypes[type1] = type; else propertyDrawerTypes.Add(type1, type); } } } foreach (var method in target.GetType().GetMethods(flags)) { if(method.IsDefined(typeof(MethodAttribute), true)) { MethodAttribute attribute = method.GetCustomAttribute(); if (!methodDrawerTypes.ContainsKey(attribute.GetType())) continue; MethodDrawer methodDrawer = Activator.CreateInstance(methodDrawerTypes[attribute.GetType()]) as MethodDrawer; if (methodDrawer != null) { methodDrawer.attribute = attribute; methodDrawer.methodInfo = method; methodDrawers.Add(methodDrawer); } } } foreach (var property in target.GetType().GetProperties(flags)) { if (property.IsDefined(typeof(PropertyAttribute), true)) { PropertyAttribute attribute = property.GetCustomAttribute(); if (!propertyDrawerTypes.ContainsKey(attribute.GetType())) continue; PropertyDrawer propertyDrawer = Activator.CreateInstance(propertyDrawerTypes[attribute.GetType()]) as PropertyDrawer; if (propertyDrawer != null) { propertyDrawer.attribute = attribute; propertyDrawer.propertyInfo = property; propertyDrawers.Add(propertyDrawer); } } } } public override void OnInspectorGUI() { base.OnInspectorGUI(); foreach (var property in propertyDrawers) { property.OnGUI(serializedObject); } foreach (var method in methodDrawers) { method.OnGUI(serializedObject); } } } public abstract class BaseAttributeDrawer : UnityEditor.PropertyDrawer { Rect copyRect = Rect.zero; Rect pasteRect = Rect.zero; public UObject target; public override float GetPropertyHeight(SerializedProperty property, GUIContent label) { InspectorAttribute _attribute = (InspectorAttribute)attribute; if (_attribute is BegingFoldAttribute && property.isExpanded) { if (_attribute.IsShow) return base.GetPropertyHeight(property, label); else return 0; } else return base.GetPropertyHeight(property, label); } public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { if (property != null) target = property.serializedObject.targetObject; InspectorAttribute _attribute = (InspectorAttribute)attribute; OnDarwBefore(position, property, label); if (!_attribute.IsShow) return; if (_attribute is BegingFoldAttribute && !property.isExpanded) return; float _width = position.width; _width -= (Convert.ToInt32(_attribute.IsEnableCopy) + Convert.ToInt32(_attribute.IsEnadlePaste)) * 43; float _btnWidth = _width; if (_attribute.IsEnableCopy) { _btnWidth += 23; copyRect.Set(_btnWidth, position.y, 40, position.height); if (GUI.Button(copyRect, "¸´ÖÆ")) Copy(property); _btnWidth += 43; } if(_attribute.IsEnadlePaste) { pasteRect.Set(_btnWidth, position.y, 40, position.height); if (GUI.Button(pasteRect, "Õ³Ìù")) Paste(property); } position.width = _width; switch (_attribute.DrawMode) { case DrawMode.EditModeAndRunTime: OnDarw(position, property, label); break; case DrawMode.OnlyEditMode: if (!EditorApplication.isPlaying) OnDarwEditMode(position, property, label); break; case DrawMode.OnlyRuntime: if (EditorApplication.isPlaying) OnDarwRuntime(position, property, label); break; default: base.OnGUI(position, property, label); break; } } public virtual void OnDarwBefore(Rect position, SerializedProperty property, GUIContent label) { } public virtual void Paste(SerializedProperty property) { property.serializedObject.Update(); switch (property.propertyType) { case SerializedPropertyType.Generic: break; case SerializedPropertyType.Integer: if (int.TryParse(EditorGUIUtility.systemCopyBuffer, out int v)) property.intValue = v; break; case SerializedPropertyType.Boolean: if (bool.TryParse(EditorGUIUtility.systemCopyBuffer, out bool b)) property.boolValue = b; break; case SerializedPropertyType.Float: string fstr = EditorGUIUtility.systemCopyBuffer.Replace("f", ""); if (float.TryParse(fstr, out float f)) property.floatValue = f; break; case SerializedPropertyType.String: property.stringValue = EditorGUIUtility.systemCopyBuffer; break; case SerializedPropertyType.Color: property.colorValue = JsonUtility.FromJson(EditorGUIUtility.systemCopyBuffer); break; case SerializedPropertyType.ObjectReference: property.objectReferenceValue = JsonUtility.FromJson(EditorGUIUtility.systemCopyBuffer); break; case SerializedPropertyType.LayerMask: break; case SerializedPropertyType.Enum: property.enumValueIndex = JsonUtility.FromJson(EditorGUIUtility.systemCopyBuffer); break; case SerializedPropertyType.Vector2: property.vector2Value = JsonUtility.FromJson(EditorGUIUtility.systemCopyBuffer); break; case SerializedPropertyType.Vector3: property.vector3Value = JsonUtility.FromJson(EditorGUIUtility.systemCopyBuffer); break; case SerializedPropertyType.Vector4: property.vector4Value = JsonUtility.FromJson(EditorGUIUtility.systemCopyBuffer); break; case SerializedPropertyType.Rect: property.rectValue = JsonUtility.FromJson(EditorGUIUtility.systemCopyBuffer); break; case SerializedPropertyType.ArraySize: property.arraySize = JsonUtility.FromJson(EditorGUIUtility.systemCopyBuffer); break; case SerializedPropertyType.Character: break; case SerializedPropertyType.AnimationCurve: property.animationCurveValue = JsonUtility.FromJson(EditorGUIUtility.systemCopyBuffer); break; case SerializedPropertyType.Bounds: property.boundsValue = JsonUtility.FromJson(EditorGUIUtility.systemCopyBuffer); break; case SerializedPropertyType.Gradient: break; case SerializedPropertyType.Quaternion: property.quaternionValue = JsonUtility.FromJson(EditorGUIUtility.systemCopyBuffer); break; case SerializedPropertyType.ExposedReference: property.exposedReferenceValue = JsonUtility.FromJson(EditorGUIUtility.systemCopyBuffer); break; case SerializedPropertyType.FixedBufferSize: break; case SerializedPropertyType.Vector2Int: property.vector2IntValue = JsonUtility.FromJson(EditorGUIUtility.systemCopyBuffer); break; case SerializedPropertyType.Vector3Int: property.vector3IntValue = JsonUtility.FromJson(EditorGUIUtility.systemCopyBuffer); break; case SerializedPropertyType.RectInt: property.rectIntValue = JsonUtility.FromJson(EditorGUIUtility.systemCopyBuffer); break; case SerializedPropertyType.BoundsInt: property.boundsIntValue = JsonUtility.FromJson(EditorGUIUtility.systemCopyBuffer); break; case SerializedPropertyType.ManagedReference: property.managedReferenceValue = JsonUtility.FromJson(EditorGUIUtility.systemCopyBuffer); break; case SerializedPropertyType.Hash128: property.hash128Value = JsonUtility.FromJson(EditorGUIUtility.systemCopyBuffer); break; default: break; } property.serializedObject.ApplyModifiedProperties(); } public virtual void Copy(SerializedProperty property) { switch (property.propertyType) { case SerializedPropertyType.Generic: break; case SerializedPropertyType.Integer: EditorGUIUtility.systemCopyBuffer=property.intValue.ToString(); break; case SerializedPropertyType.Boolean: EditorGUIUtility.systemCopyBuffer = property.boolValue.ToString(); break; case SerializedPropertyType.Float: EditorGUIUtility.systemCopyBuffer = property.floatValue + "f"; break; case SerializedPropertyType.String: EditorGUIUtility.systemCopyBuffer = property.stringValue; break; case SerializedPropertyType.Color: EditorGUIUtility.systemCopyBuffer = JsonUtility.ToJson(property.colorValue); break; case SerializedPropertyType.ObjectReference: EditorGUIUtility.systemCopyBuffer = JsonUtility.ToJson(property.objectReferenceValue); break; case SerializedPropertyType.LayerMask: break; case SerializedPropertyType.Enum: EditorGUIUtility.systemCopyBuffer = JsonUtility.ToJson(property.enumValueIndex); break; case SerializedPropertyType.Vector2: EditorGUIUtility.systemCopyBuffer = JsonUtility.ToJson(property.vector2Value); break; case SerializedPropertyType.Vector3: EditorGUIUtility.systemCopyBuffer = JsonUtility.ToJson(property.vector3Value); break; case SerializedPropertyType.Vector4: EditorGUIUtility.systemCopyBuffer = JsonUtility.ToJson(property.vector4Value); break; case SerializedPropertyType.Rect: EditorGUIUtility.systemCopyBuffer = JsonUtility.ToJson(property.rectValue); break; case SerializedPropertyType.ArraySize: EditorGUIUtility.systemCopyBuffer = JsonUtility.ToJson(property.arraySize); break; case SerializedPropertyType.Character: break; case SerializedPropertyType.AnimationCurve: EditorGUIUtility.systemCopyBuffer = JsonUtility.ToJson(property.animationCurveValue); break; case SerializedPropertyType.Bounds: EditorGUIUtility.systemCopyBuffer = JsonUtility.ToJson(property.boundsValue); break; case SerializedPropertyType.Gradient: break; case SerializedPropertyType.Quaternion: EditorGUIUtility.systemCopyBuffer = JsonUtility.ToJson(property.quaternionValue); break; case SerializedPropertyType.ExposedReference: EditorGUIUtility.systemCopyBuffer = JsonUtility.ToJson(property.exposedReferenceValue); break; case SerializedPropertyType.FixedBufferSize: break; case SerializedPropertyType.Vector2Int: EditorGUIUtility.systemCopyBuffer = JsonUtility.ToJson(property.vector2IntValue); break; case SerializedPropertyType.Vector3Int: EditorGUIUtility.systemCopyBuffer = JsonUtility.ToJson(property.vector3IntValue); break; case SerializedPropertyType.RectInt: EditorGUIUtility.systemCopyBuffer = JsonUtility.ToJson(property.rectIntValue); break; case SerializedPropertyType.BoundsInt: EditorGUIUtility.systemCopyBuffer = JsonUtility.ToJson(property.boundsIntValue); break; case SerializedPropertyType.ManagedReference: EditorGUIUtility.systemCopyBuffer = JsonUtility.ToJson(property.managedReferenceValue); break; case SerializedPropertyType.Hash128: EditorGUIUtility.systemCopyBuffer = JsonUtility.ToJson(property.hash128Value); break; default: break; } } public virtual void OnDarwRuntime(Rect position, SerializedProperty property, GUIContent label) { DrawUI(position, property, label); } public virtual void OnDarwEditMode(Rect position, SerializedProperty property, GUIContent label) { DrawUI(position, property, label); } public virtual void OnDarw(Rect position, SerializedProperty property, GUIContent label) { DrawUI(position, property, label); } public abstract void DrawUI(Rect position, SerializedProperty property, GUIContent label); public void MarkerChange() { if (target == null) return; EditorUtility.SetDirty(target); if (EditorApplication.isPlaying) return; Component component = target as Component; if (component != null && component.gameObject.scene != null) { EditorSceneManager.MarkSceneDirty(component.gameObject.scene); } } } public abstract class MethodDrawer { public MethodInfo methodInfo; public MethodAttribute attribute; public virtual void OnGUI(SerializedObject serializedObject) { } } public abstract class PropertyDrawer { public PropertyInfo propertyInfo; public PropertyAttribute attribute; public UObject target; public EventButtonAttribute buttonAttribute; public GetTransFormValueAttribute formValueAttribute; public string Name; public virtual void OnGUI(SerializedObject serializedObject) { target = serializedObject.targetObject; Name = string.IsNullOrEmpty(attribute.Lable) ? propertyInfo.Name : attribute.Lable; buttonAttribute = target?.GetType().GetCustomAttribute(); formValueAttribute = target?.GetType().GetCustomAttribute(); using(new EditorGUILayout.HorizontalScope()) { switch (attribute.DrawMode) { case DrawMode.EditModeAndRunTime: OnDarw(serializedObject); break; case DrawMode.OnlyEditMode: if (!EditorApplication.isPlaying) OnDarwEditMode(serializedObject); break; case DrawMode.OnlyRuntime: if (EditorApplication.isPlaying) OnDarwRuntime(serializedObject); break; default: DrawUI(serializedObject); break; } if (attribute.IsEnableCopy) { if (GUILayout.Button("¸´ÖÆ",GUILayout.ExpandWidth(false))) Copy(serializedObject); } if (attribute.IsEnadlePaste) { if (GUILayout.Button("Õ³Ìù", GUILayout.ExpandWidth(false))) Paste(serializedObject); } if(buttonAttribute!=null) { if(GUILayout.Button(buttonAttribute.Lable, GUILayout.ExpandWidth(false))) { buttonAttribute.TypeValue.GetMethod(buttonAttribute.ActionName)?.Invoke(target,null); } } if(formValueAttribute!=null) { if(GUILayout.Button(EditorGUIUtility.IconContent("Custom@2x").image, GUILayout.Width(30), GUILayout.Height(20))) { Vector3 value = (Vector3)propertyInfo.GetValue(target); if(Selection.activeTransform) switch (formValueAttribute.TranType) { case TranType.None: break; case TranType.Position: value = Selection.activeTransform.position; break; case TranType.Rotation: value = Selection.activeTransform.rotation.eulerAngles; break; case TranType.Scale: value = Selection.activeTransform.localScale; break; default: break; } propertyInfo.SetValue(target, value); } } } } public virtual void Paste(SerializedObject serializedObject) { try { propertyInfo.SetValue(target, EditorGUIUtility.systemCopyBuffer); MarkerChange(); } catch { } } public virtual void Copy(SerializedObject serializedObject) { EditorGUIUtility.systemCopyBuffer = propertyInfo.GetValue(target).ToString(); } public virtual void OnDarwRuntime(SerializedObject serializedObject) { DrawUI(serializedObject); } public virtual void OnDarwEditMode(SerializedObject serializedObject) { DrawUI(serializedObject); } public virtual void OnDarw(SerializedObject serializedObject) { DrawUI(serializedObject); } public void MarkerChange() { if (target == null) return; EditorUtility.SetDirty(target); if (EditorApplication.isPlaying) return; Component component = target as Component; if (component != null && component.gameObject.scene != null) { EditorSceneManager.MarkSceneDirty(component.gameObject.scene); } } public abstract void DrawUI(SerializedObject serializedObject); } [CustomPropertyDrawer(typeof(LabelAttribute),true)] public class LabelAttributeDrawer:BaseAttributeDrawer { public override void DrawUI(Rect position, SerializedProperty property, GUIContent label) { LabelAttribute _attribute = (LabelAttribute)attribute; label.text = _attribute.Text; EditorGUI.PropertyField(position, property, label); } } [CustomPropertyDrawer(typeof(EventButtonAttribute), true)] public class EventButtonAttributeDrawer : BaseAttributeDrawer { public override void DrawUI(Rect position, SerializedProperty property, GUIContent label) { EventButtonAttribute _attribute = (EventButtonAttribute)attribute; float width = position.width - 33; width += 23; if (GUI.Button(new Rect(width,position.y,30,position.height),_attribute.Lable)) { _attribute.TypeValue.GetMethod(_attribute.ActionName).Invoke(target, null); } EditorGUI.PropertyField(new Rect(position.x,position.y,width-23,position.height), property, label); } } [CustomPropertyDrawer(typeof(DropdownAttribute),true)] public class DropdownAttributeDrawer : BaseAttributeDrawer { public override void DrawUI(Rect position, SerializedProperty property, GUIContent label) { object value = fieldInfo.GetValue(property.serializedObject.targetObject); DropdownAttribute dropdown = attribute as DropdownAttribute; int selectIndex = dropdown.Values.IndexOf(value); if (selectIndex < 0) { selectIndex = 0; fieldInfo.SetValue(property.serializedObject.targetObject, dropdown.Values[selectIndex]); MarkerChange(); } EditorGUI.BeginChangeCheck(); int newIndex = EditorGUI.Popup(position,label.text, selectIndex, dropdown.DisplayOptions.ToArray()); if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(target, "Dropdown"); fieldInfo.SetValue(target, dropdown.Values[newIndex]); MarkerChange(); } } } [CustomPropertyDrawer(typeof(SceneAttribute))] public class SceneAttributeDrawer : BaseAttributeDrawer { public override void DrawUI(Rect position, SerializedProperty property, GUIContent label) { object value = fieldInfo.GetValue(target); EditorGUI.BeginChangeCheck(); SceneAsset scene = EditorGUI.ObjectField(position,label, AssetDatabase.LoadAssetAtPath((string)value), typeof(SceneAsset), false) as SceneAsset; if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(target, "Scene"); fieldInfo.SetValue(target, AssetDatabase.GetAssetPath(scene)); MarkerChange(); } } } [CustomPropertyDrawer(typeof(RelevancyShowAttribute))] public class RelevancyShowAttributeDrawer : BaseAttributeDrawer { BindingFlags flags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Default | BindingFlags.Instance; public override void DrawUI(Rect position, SerializedProperty property, GUIContent label) { EditorGUI.PropertyField(position, property, label); } public override float GetPropertyHeight(SerializedProperty property, GUIContent label) { RelevancyShowAttribute _attribute = attribute as RelevancyShowAttribute; MemberInfo[] member = property.serializedObject.targetObject.GetType().GetMember(_attribute.FieldName, flags); if (member != null && member.Length > 0) { if (member[0].MemberType == MemberTypes.Field) _attribute.IsShow = (member[0] as FieldInfo).GetValue(property.serializedObject.targetObject).Equals(_attribute.ShowValue); else if (member[0].MemberType == MemberTypes.Property) _attribute.IsShow = (member[0] as PropertyInfo).GetValue(property.serializedObject.targetObject).Equals(_attribute.ShowValue); else if (member[0].MemberType == MemberTypes.Method) _attribute.IsShow = (member[0] as MethodInfo).Invoke(property.serializedObject.targetObject, null).Equals(_attribute.ShowValue); } return base.GetPropertyHeight(property, label); } } [CustomPropertyDrawer(typeof(OnlyReadAttribute))] public class OnlyReadAttributeDrawer : BaseAttributeDrawer { public override void DrawUI(Rect position, SerializedProperty property, GUIContent label) { GUI.enabled = false; EditorGUI.PropertyField(position, property, label); GUI.enabled = true; } } [CustomPropertyDrawer(typeof(BegingFoldAttribute))] public class BegingFoldAttributeDrawer : BaseAttributeDrawer { int count = 0; BindingFlags flags = BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; public override void OnDarwBefore(Rect position, SerializedProperty property, GUIContent label) { BegingFoldAttribute _attribute = attribute as BegingFoldAttribute; property.isExpanded = EditorGUI.Foldout(position, property.isExpanded, _attribute.Label); } public override void DrawUI(Rect position, SerializedProperty property, GUIContent label) { position.y += 23; position.height = 20; EditorGUI.PropertyField(position, property, label); } public override float GetPropertyHeight(SerializedProperty property, GUIContent label) { using (SerializedProperty iterator = property.serializedObject.GetIterator()) { HashSet fieldPaths = new HashSet(); bool flags1 = false; while (iterator.NextVisible(true)) { SerializedProperty _property = property.serializedObject.FindProperty(iterator.name); if (!flags1) flags1 = _property.propertyPath == property.propertyPath; if (_property != null && !fieldPaths.Contains(_property.propertyPath)&&flags1) { fieldPaths.Add(_property.propertyPath); FieldInfo fieldInfo = _property.serializedObject.targetObject.GetType().GetField(_property.name, flags); InspectorAttribute _attribute = fieldInfo.GetCustomAttribute(); if(_attribute!=null) { if (fieldInfo.GetCustomAttribute() != null) { count++; } if(fieldInfo.GetCustomAttribute() != null) { count--; if (count == 0) break; } } _property.isExpanded = property.isExpanded; } } } return base.GetPropertyHeight(property, label)+23; } } [CustomPropertyDrawer(typeof(GetTransFormValueAttribute))] public class GetTransFormValueAttributeDrawer : BaseAttributeDrawer { public override void DrawUI(Rect position, SerializedProperty property, GUIContent label) { GetTransFormValueAttribute _attribute = (GetTransFormValueAttribute)attribute; float width = position.width - 33; width += 23; if (GUI.Button(new Rect(width, position.y, 30, position.height), EditorGUIUtility.IconContent("Custom@2x").image)) { Vector3 value = property.vector3Value; if (Selection.activeTransform) switch (_attribute.TranType) { case TranType.None: break; case TranType.Position: value = Selection.activeTransform.position; break; case TranType.Rotation: value = Selection.activeTransform.rotation.eulerAngles; break; case TranType.Scale: value = Selection.activeTransform.localScale; break; default: break; } property.vector3Value = value; } EditorGUI.PropertyField(new Rect(position.x, position.y, width-23, position.height), property, label); } } [TCustomPropertyDrawer(typeof(PropertyAttribute))] public class PropertyAttributeDrawer : PropertyDrawer { public override void DrawUI(SerializedObject serializedObject) { if (propertyInfo.CanWrite) { CanWritePainting(); } else { ReadOnlyPainting(); } } private void CanWritePainting() { EditorGUI.BeginChangeCheck(); object value = propertyInfo.GetValue(target); object newValue = value; if (propertyInfo.PropertyType.IsEnum) { Enum realValue = EditorGUILayout.EnumPopup(Name, (Enum)value); if (EditorGUI.EndChangeCheck()) newValue = realValue; } else if (propertyInfo.PropertyType == typeof(string)) { string realValue = EditorGUILayout.TextField(Name, (string)value); if (EditorGUI.EndChangeCheck()) newValue = realValue; } else if (propertyInfo.PropertyType == typeof(int)) { int realValue = EditorGUILayout.IntField(Name, (int)value); if (EditorGUI.EndChangeCheck()) newValue = realValue; } else if (propertyInfo.PropertyType == typeof(float)) { float realValue = EditorGUILayout.FloatField(Name, (float)value); if (EditorGUI.EndChangeCheck()) newValue = realValue; } else if (propertyInfo.PropertyType == typeof(bool)) { bool realValue = EditorGUILayout.Toggle(Name, (bool)value); if (EditorGUI.EndChangeCheck()) newValue = realValue; } else if (propertyInfo.PropertyType == typeof(Vector2)) { Vector2 realValue = EditorGUILayout.Vector2Field(Name, (Vector2)value); if (EditorGUI.EndChangeCheck()) newValue = realValue; } else if (propertyInfo.PropertyType == typeof(Vector3)) { Vector3 realValue = EditorGUILayout.Vector3Field(Name, (Vector3)value); if (EditorGUI.EndChangeCheck()) newValue = realValue; } else if (propertyInfo.PropertyType == typeof(Color)) { Color realValue = EditorGUILayout.ColorField(Name, (Color)value); if (EditorGUI.EndChangeCheck()) newValue = realValue; } else if (propertyInfo.PropertyType.IsSubclassOf(typeof(UObject))) { UObject realValue = EditorGUILayout.ObjectField(Name, value as UObject, propertyInfo.PropertyType, true); if (EditorGUI.EndChangeCheck()) newValue = realValue; } else { string realValue = EditorGUILayout.TextField(Name, value != null ? value.ToString() : "null"); if(EditorGUI.EndChangeCheck()) newValue = realValue; } if (value != newValue) { Undo.RecordObject(target, "propertyInfo Changed"); propertyInfo.SetValue(target, newValue); MarkerChange(); } } private void ReadOnlyPainting() { GUI.enabled = false; object value = propertyInfo.GetValue(target); if (propertyInfo.PropertyType.IsEnum) { EditorGUILayout.EnumPopup(Name, (Enum)value); } else if (propertyInfo.PropertyType == typeof(string)) { EditorGUILayout.TextField(Name, (string)value); } else if (propertyInfo.PropertyType == typeof(int)) { EditorGUILayout.IntField(Name, (int)value); } else if (propertyInfo.PropertyType == typeof(float)) { EditorGUILayout.FloatField(Name, (float)value); } else if (propertyInfo.PropertyType == typeof(bool)) { EditorGUILayout.Toggle(Name, (bool)value); } else if (propertyInfo.PropertyType == typeof(Vector2)) { EditorGUILayout.Vector2Field(Name, (Vector2)value); } else if (propertyInfo.PropertyType == typeof(Vector3)) { EditorGUILayout.Vector3Field(Name, (Vector3)value); } else if (propertyInfo.PropertyType == typeof(Color)) { EditorGUILayout.ColorField(Name, (Color)value); } else if (propertyInfo.PropertyType.IsSubclassOf(typeof(UObject))) { EditorGUILayout.ObjectField(Name, value as UObject, propertyInfo.PropertyType, false); } else { EditorGUILayout.TextField(Name, value != null ? value.ToString() : "null"); } GUI.enabled = true; } } [CustomMethodDrawer(typeof(ButtonAttribute))] public class ButtonAttributeDrawer : MethodDrawer { BindingFlags flags = BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Default; public bool IsActive = true; public string Name; public override void OnGUI(SerializedObject serializedObject) { ButtonAttribute _attribute = attribute as ButtonAttribute; Name = string.IsNullOrEmpty(_attribute.Name) ? methodInfo.Name : _attribute.Name; if (!string.IsNullOrEmpty(_attribute.CriteriaName)) { MemberInfo[] member = serializedObject.targetObject.GetType().GetMember(_attribute.CriteriaName, flags); if (member != null && member.Length > 0) { if (member[0].MemberType == MemberTypes.Field) IsActive = (bool)(member[0] as FieldInfo).GetValue(serializedObject.targetObject); else if (member[0].MemberType == MemberTypes.Property) IsActive = (bool)(member[0] as PropertyInfo).GetValue(serializedObject.targetObject); else if (member[0].MemberType == MemberTypes.Method) IsActive = (bool)(member[0] as MethodInfo).Invoke(serializedObject.targetObject, null); } GUI.enabled = IsActive == _attribute.CriteriaVaule; } if (GUILayout.Button(Name)) { if (methodInfo.IsStatic) methodInfo.Invoke(null, _attribute.Parameter); else methodInfo.Invoke(serializedObject.targetObject, _attribute.Parameter); } GUI.enabled = true; } } }