Skip to content

Commit

Permalink
feat: ODIN inspector support (close #32, #33)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mefodei authored and favoyang committed Jul 6, 2020
1 parent eae9feb commit e7bfcb8
Show file tree
Hide file tree
Showing 12 changed files with 254 additions and 166 deletions.
4 changes: 3 additions & 1 deletion Editor/AddressableImportSettings.cs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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<AddressableImportRule> rules;

[ButtonMethod]
Expand Down
8 changes: 8 additions & 0 deletions Editor/Attributes.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions Editor/Attributes/ButtonMethodAttribute.cs
Original file line number Diff line number Diff line change
@@ -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
{
}
}

File renamed without changes.
56 changes: 56 additions & 0 deletions Editor/Helper/AddressableImportSettingsEditor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/// <summary>
/// ButtonMethodAttribute,
/// modified from https://github.com/Deadcows/MyBox/blob/master/Attributes/ButtonMethodAttribute.cs
/// </summary>
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<MethodInfo> _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
}
}
}
11 changes: 11 additions & 0 deletions Editor/Helper/AddressableImportSettingsEditor.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

101 changes: 101 additions & 0 deletions Editor/Helper/AddressableImporterMethodHandler.cs
Original file line number Diff line number Diff line change
@@ -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<MethodInfo> CollectValidMembers(Type type)
{
List<MethodInfo> 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<MethodInfo>();
methods.Add(method);
}
}

return methods;
}

public static void OnInspectorGUI(UnityEngine.Object target, List<MethodInfo> 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 <color=brown>{0}</color>.Reason: Member is not a method but has EditorButtonAttribute!",
member.Name));
return false;
}

if (method.GetParameters().Length > 0)
{
Debug.LogWarning(
string.Format("Method <color=brown>{0}</color>.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));
}


/// <summary>
/// "CamelCaseString" => "Camel Case String"
/// COPY OF MyString.SplitCamelCase()
/// </summary>
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;
}
}
}
3 changes: 3 additions & 0 deletions Editor/Helper/AddressableImporterMethodHandler.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

44 changes: 44 additions & 0 deletions Editor/Helper/AddressableImporterOdinHandler.cs
Original file line number Diff line number Diff line change
@@ -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
}
11 changes: 11 additions & 0 deletions Editor/Helper/AddressableImporterOdinHandler.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit e7bfcb8

Please sign in to comment.