Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/odin inspector support #33

Closed
Closed
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
{
}
}

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 AddressablesImporterOdinHandler : 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