From e7bfcb880da19f5fc06a76b2ffdc2fb39e539236 Mon Sep 17 00:00:00 2001 From: Mefodei Date: Mon, 6 Jul 2020 23:11:29 +0800 Subject: [PATCH] feat: ODIN inspector support (close #32, #33) --- Editor/AddressableImportSettings.cs | 4 +- Editor/Attributes.meta | 8 + Editor/Attributes/ButtonMethodAttribute.cs | 15 ++ .../ButtonMethodAttribute.cs.meta | 0 .../Helper/AddressableImportSettingsEditor.cs | 56 ++++++ .../AddressableImportSettingsEditor.cs.meta | 11 ++ .../AddressableImporterMethodHandler.cs | 101 +++++++++++ .../AddressableImporterMethodHandler.cs.meta | 3 + .../Helper/AddressableImporterOdinHandler.cs | 44 +++++ .../AddressableImporterOdinHandler.cs.meta | 11 ++ Editor/Helper/ButtonMethodAttribute.cs | 163 ------------------ .../Unity.AddressableImporter.Editor.asmdef | 4 +- 12 files changed, 254 insertions(+), 166 deletions(-) create mode 100644 Editor/Attributes.meta create mode 100644 Editor/Attributes/ButtonMethodAttribute.cs rename Editor/{Helper => Attributes}/ButtonMethodAttribute.cs.meta (100%) create mode 100644 Editor/Helper/AddressableImportSettingsEditor.cs create mode 100644 Editor/Helper/AddressableImportSettingsEditor.cs.meta create mode 100644 Editor/Helper/AddressableImporterMethodHandler.cs create mode 100644 Editor/Helper/AddressableImporterMethodHandler.cs.meta create mode 100644 Editor/Helper/AddressableImporterOdinHandler.cs create mode 100644 Editor/Helper/AddressableImporterOdinHandler.cs.meta delete mode 100644 Editor/Helper/ButtonMethodAttribute.cs diff --git a/Editor/AddressableImportSettings.cs b/Editor/AddressableImportSettings.cs index 795140d..2ac3b88 100644 --- a/Editor/AddressableImportSettings.cs +++ b/Editor/AddressableImportSettings.cs @@ -1,7 +1,6 @@ using UnityEngine; using UnityEditor; using UnityEditor.AddressableAssets; -using UnityEditor.AddressableAssets.Settings; using System.Collections.Generic; using System.Linq; using UnityAddressableImporter.Helper; @@ -17,6 +16,9 @@ public class AddressableImportSettings : ScriptableObject public bool allowGroupCreation = false; [Tooltip("Rules for managing imported assets.")] +#if ODIN_INSPECTOR + [Sirenix.OdinInspector.ListDrawerSettings(HideAddButton = false,Expanded = false,DraggableItems = true,HideRemoveButton = false)] +#endif public List rules; [ButtonMethod] diff --git a/Editor/Attributes.meta b/Editor/Attributes.meta new file mode 100644 index 0000000..f22aa63 --- /dev/null +++ b/Editor/Attributes.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c56236d4c5626ba46a8f73847c0129aa +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Attributes/ButtonMethodAttribute.cs b/Editor/Attributes/ButtonMethodAttribute.cs new file mode 100644 index 0000000..b1e1214 --- /dev/null +++ b/Editor/Attributes/ButtonMethodAttribute.cs @@ -0,0 +1,15 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + + +namespace UnityAddressableImporter.Helper +{ + using System; + + [AttributeUsage(AttributeTargets.Method)] + public class ButtonMethodAttribute : PropertyAttribute + { + } +} + diff --git a/Editor/Helper/ButtonMethodAttribute.cs.meta b/Editor/Attributes/ButtonMethodAttribute.cs.meta similarity index 100% rename from Editor/Helper/ButtonMethodAttribute.cs.meta rename to Editor/Attributes/ButtonMethodAttribute.cs.meta diff --git a/Editor/Helper/AddressableImportSettingsEditor.cs b/Editor/Helper/AddressableImportSettingsEditor.cs new file mode 100644 index 0000000..bf6c42a --- /dev/null +++ b/Editor/Helper/AddressableImportSettingsEditor.cs @@ -0,0 +1,56 @@ +/// +/// ButtonMethodAttribute, +/// modified from https://github.com/Deadcows/MyBox/blob/master/Attributes/ButtonMethodAttribute.cs +/// +using UnityEngine; + +namespace UnityAddressableImporter.Helper.Internal +{ + using System; + using System.Collections.Generic; + using System.Reflection; + using Editor.Helper; + using UnityEditor; + + + [CustomEditor(typeof(AddressableImportSettings), true), CanEditMultipleObjects] + public class AddressableImportSettingsEditor : Editor + { + private List _methods; + private ScriptableObject _target; + private AddressableImporterOdinHandler _drawer; + + private void OnEnable() + { + _target = target as ScriptableObject; + _drawer = _drawer ?? new AddressableImporterOdinHandler(); + if (_target == null) return; + + _drawer.Initialize(target); + _methods = AddressableImporterMethodHandler.CollectValidMembers(_target.GetType()); + } + + private void OnDisable() + { + _drawer.Dispose(); + } + + public override void OnInspectorGUI() + { + DrawBaseEditor(); + + if (_methods == null) return; + + AddressableImporterMethodHandler.OnInspectorGUI(_target, _methods); + } + + private void DrawBaseEditor() + { +#if ODIN_INSPECTOR + _drawer.Draw(); +#else + base.OnInspectorGUI(); +#endif + } + } +} \ No newline at end of file diff --git a/Editor/Helper/AddressableImportSettingsEditor.cs.meta b/Editor/Helper/AddressableImportSettingsEditor.cs.meta new file mode 100644 index 0000000..d1799e8 --- /dev/null +++ b/Editor/Helper/AddressableImportSettingsEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a6a4a45e7520cd740a443693fd7ec2d1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Helper/AddressableImporterMethodHandler.cs b/Editor/Helper/AddressableImporterMethodHandler.cs new file mode 100644 index 0000000..9ab8514 --- /dev/null +++ b/Editor/Helper/AddressableImporterMethodHandler.cs @@ -0,0 +1,101 @@ +namespace UnityAddressableImporter.Helper.Internal +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Reflection; + using System.Text.RegularExpressions; + using UnityEditor; + using UnityEngine; + + public static class AddressableImporterMethodHandler + { + public static List CollectValidMembers(Type type) + { + List methods = null; + + var members = type.GetMembers(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) + .Where(IsButtonMethod); + + foreach (var member in members) + { + var method = member as MethodInfo; + if (IsValidMember(method, member)) + { + if (methods == null) methods = new List(); + methods.Add(method); + } + } + + return methods; + } + + public static void OnInspectorGUI(UnityEngine.Object target, List methods) + { + EditorGUILayout.Space(); + + foreach (MethodInfo method in methods) + { + if (GUILayout.Button(SplitCamelCase(method.Name))) InvokeMethod(target, method); + } + } + + private static void InvokeMethod(UnityEngine.Object target, MethodInfo method) + { + var result = method.Invoke(target, null); + + if (result != null) + { + var message = string.Format("{0} \nResult of Method '{1}' invocation on object {2}", result, method.Name, target.name); + Debug.Log(message, target); + } + } + + private static bool IsValidMember(MethodInfo method, MemberInfo member) + { + if (method == null) + { + Debug.LogWarning( + string.Format("Property {0}.Reason: Member is not a method but has EditorButtonAttribute!", + member.Name)); + return false; + } + + if (method.GetParameters().Length > 0) + { + Debug.LogWarning( + string.Format("Method {0}.Reason: Methods with parameters is not supported by EditorButtonAttribute!", + method.Name)); + return false; + } + + return true; + } + + private static bool IsButtonMethod(MemberInfo memberInfo) + { + return Attribute.IsDefined(memberInfo, typeof(ButtonMethodAttribute)); + } + + + /// + /// "CamelCaseString" => "Camel Case String" + /// COPY OF MyString.SplitCamelCase() + /// + private static string SplitCamelCase(string camelCaseString) + { + if (string.IsNullOrEmpty(camelCaseString)) return camelCaseString; + + string camelCase = Regex.Replace(Regex.Replace(camelCaseString, @"(\P{Ll})(\P{Ll}\p{Ll})", "$1 $2"), @"(\p{Ll})(\P{Ll})", "$1 $2"); + string firstLetter = camelCase.Substring(0, 1).ToUpper(); + + if (camelCaseString.Length > 1) + { + string rest = camelCase.Substring(1); + + return firstLetter + rest; + } + return firstLetter; + } + } +} \ No newline at end of file diff --git a/Editor/Helper/AddressableImporterMethodHandler.cs.meta b/Editor/Helper/AddressableImporterMethodHandler.cs.meta new file mode 100644 index 0000000..56fc093 --- /dev/null +++ b/Editor/Helper/AddressableImporterMethodHandler.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 952a24021e5b4152bf5e54b3081297b1 +timeCreated: 1591269066 \ No newline at end of file diff --git a/Editor/Helper/AddressableImporterOdinHandler.cs b/Editor/Helper/AddressableImporterOdinHandler.cs new file mode 100644 index 0000000..e63ad5e --- /dev/null +++ b/Editor/Helper/AddressableImporterOdinHandler.cs @@ -0,0 +1,44 @@ +namespace UnityAddressableImporter.Editor.Helper +{ + using System; + using Object = UnityEngine.Object; + +#if ODIN_INSPECTOR + + using Sirenix.OdinInspector.Editor; + using Sirenix.OdinInspector; + + public class AddressableImporterOdinHandler : IDisposable + { + private Object _target; + private PropertyTree _drawer; + + public void Initialize(Object target) + { + _target = target; + _drawer = PropertyTree.Create(_target); + } + + public void Draw() => _drawer?.Draw(false); + + public void Dispose() + { + _target = null; + _drawer?.Dispose(); + _drawer = null; + } + } + +#else + + public class AddressableImporterOdinHandler : IDisposable + { + public void Initialize(Object target) { } + + public void Draw() { } + + public void Dispose() { } + } + +#endif +} diff --git a/Editor/Helper/AddressableImporterOdinHandler.cs.meta b/Editor/Helper/AddressableImporterOdinHandler.cs.meta new file mode 100644 index 0000000..736d8d1 --- /dev/null +++ b/Editor/Helper/AddressableImporterOdinHandler.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 36b62799a4bc2d14ea554520750092db +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Helper/ButtonMethodAttribute.cs b/Editor/Helper/ButtonMethodAttribute.cs deleted file mode 100644 index bee45b2..0000000 --- a/Editor/Helper/ButtonMethodAttribute.cs +++ /dev/null @@ -1,163 +0,0 @@ -/// -/// ButtonMethodAttribute, -/// modified from https://github.com/Deadcows/MyBox/blob/master/Attributes/ButtonMethodAttribute.cs -/// -using System; -using System.Text.RegularExpressions; -using UnityEngine; - -namespace UnityAddressableImporter.Helper -{ - [AttributeUsage(AttributeTargets.Method)] - public class ButtonMethodAttribute : PropertyAttribute - { - } -} - -#if UNITY_EDITOR -namespace UnityAddressableImporter.Helper.Internal -{ - using System.Linq; - using System.Collections.Generic; - using System.Reflection; - using UnityEditor; - - // [CustomEditor(typeof(MonoBehaviour), true), CanEditMultipleObjects] - // public class ButtonMethodMonoBehaviourEditor : Editor - // { - // private List _methods; - // private MonoBehaviour _target; - - // private void OnEnable() - // { - // _target = target as MonoBehaviour; - // if (_target == null) return; - - // _methods = ButtonMethodHandler.CollectValidMembers(_target.GetType()); - // } - - // public override void OnInspectorGUI() - // { - // base.OnInspectorGUI(); - // if (_methods == null) return; - - // ButtonMethodHandler.OnInspectorGUI(_target, _methods); - // } - // } - - - [CustomEditor(typeof(AddressableImportSettings), true), CanEditMultipleObjects] - public class ButtonMethodScriptableObjectEditor : Editor - { - private List _methods; - private ScriptableObject _target; - - private void OnEnable() - { - _target = target as ScriptableObject; - if (_target == null) return; - - _methods = ButtonMethodHandler.CollectValidMembers(_target.GetType()); - } - - public override void OnInspectorGUI() - { - base.OnInspectorGUI(); - if (_methods == null) return; - - ButtonMethodHandler.OnInspectorGUI(_target, _methods); - } - } - - public static class ButtonMethodHandler - { - public static List CollectValidMembers(Type type) - { - List methods = null; - - var members = type.GetMembers(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) - .Where(IsButtonMethod); - - foreach (var member in members) - { - var method = member as MethodInfo; - if (IsValidMember(method, member)) - { - if (methods == null) methods = new List(); - methods.Add(method); - } - } - - return methods; - } - - public static void OnInspectorGUI(UnityEngine.Object target, List methods) - { - EditorGUILayout.Space(); - - foreach (MethodInfo method in methods) - { - if (GUILayout.Button(SplitCamelCase(method.Name))) InvokeMethod(target, method); - } - } - - private static void InvokeMethod(UnityEngine.Object target, MethodInfo method) - { - var result = method.Invoke(target, null); - - if (result != null) - { - var message = string.Format("{0} \nResult of Method '{1}' invocation on object {2}", result, method.Name, target.name); - Debug.Log(message, target); - } - } - - private static bool IsValidMember(MethodInfo method, MemberInfo member) - { - if (method == null) - { - Debug.LogWarning( - string.Format("Property {0}.Reason: Member is not a method but has EditorButtonAttribute!", - member.Name)); - return false; - } - - if (method.GetParameters().Length > 0) - { - Debug.LogWarning( - string.Format("Method {0}.Reason: Methods with parameters is not supported by EditorButtonAttribute!", - method.Name)); - return false; - } - - return true; - } - - private static bool IsButtonMethod(MemberInfo memberInfo) - { - return Attribute.IsDefined(memberInfo, typeof(ButtonMethodAttribute)); - } - - - /// - /// "CamelCaseString" => "Camel Case String" - /// COPY OF MyString.SplitCamelCase() - /// - private static string SplitCamelCase(string camelCaseString) - { - if (string.IsNullOrEmpty(camelCaseString)) return camelCaseString; - - string camelCase = Regex.Replace(Regex.Replace(camelCaseString, @"(\P{Ll})(\P{Ll}\p{Ll})", "$1 $2"), @"(\p{Ll})(\P{Ll})", "$1 $2"); - string firstLetter = camelCase.Substring(0, 1).ToUpper(); - - if (camelCaseString.Length > 1) - { - string rest = camelCase.Substring(1); - - return firstLetter + rest; - } - return firstLetter; - } - } -} -#endif \ No newline at end of file diff --git a/Editor/Unity.AddressableImporter.Editor.asmdef b/Editor/Unity.AddressableImporter.Editor.asmdef index ac91906..14ab644 100644 --- a/Editor/Unity.AddressableImporter.Editor.asmdef +++ b/Editor/Unity.AddressableImporter.Editor.asmdef @@ -4,7 +4,6 @@ "Unity.Addressables", "Unity.Addressables.Editor" ], - "optionalUnityReferences": [], "includePlatforms": [ "Editor" ], @@ -14,5 +13,6 @@ "precompiledReferences": [], "autoReferenced": true, "defineConstraints": [], - "versionDefines": [] + "versionDefines": [], + "noEngineReferences": false } \ No newline at end of file