121 lines
4.0 KiB
C#
121 lines
4.0 KiB
C#
|
#if UNITY_EDITOR
|
||
|
namespace Sirenix.OdinInspector.Demos
|
||
|
{
|
||
|
using System;
|
||
|
using UnityEngine;
|
||
|
|
||
|
#if UNITY_EDITOR
|
||
|
|
||
|
using Sirenix.OdinInspector.Editor;
|
||
|
using System.Reflection;
|
||
|
using Sirenix.Utilities;
|
||
|
using Sirenix.Utilities.Editor;
|
||
|
|
||
|
#endif
|
||
|
|
||
|
// Example demonstrating how reflection can be used to enhance custom drawers.
|
||
|
[TypeInfoBox(
|
||
|
"This example demonstrates how reflection can be used to extend drawers from what otherwise would be possible.\n\n" +
|
||
|
"In this case, a user can specify one of their own methods to receive a callback from the drawer chain.\n\n" +
|
||
|
"Note that this is a manual approach; it is recommended to use ValueResolver<T> and ActionResolver instead.")]
|
||
|
public class ReflectionExample : MonoBehaviour
|
||
|
{
|
||
|
[OnClickMethod("OnClick")]
|
||
|
public int InstanceMethod;
|
||
|
|
||
|
[OnClickMethod("StaticOnClick")]
|
||
|
public int StaticMethod;
|
||
|
|
||
|
[OnClickMethod("InvalidOnClick")]
|
||
|
public int InvalidMethod;
|
||
|
|
||
|
private void OnClick()
|
||
|
{
|
||
|
Debug.Log("Hello?");
|
||
|
}
|
||
|
|
||
|
private static void StaticOnClick()
|
||
|
{
|
||
|
Debug.Log("Static Hello?");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Attribute with name of call back method.
|
||
|
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
|
||
|
public class OnClickMethodAttribute : Attribute
|
||
|
{
|
||
|
public string MethodName { get; private set; }
|
||
|
|
||
|
public OnClickMethodAttribute(string methodName)
|
||
|
{
|
||
|
this.MethodName = methodName;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#if UNITY_EDITOR
|
||
|
|
||
|
// Place the drawer script file in an Editor folder.
|
||
|
// Remember to add the OdinDrawer to your custom drawer classes, or they will not be found by Odin.
|
||
|
public class OnClickMethodAttributeDrawer : OdinAttributeDrawer<OnClickMethodAttribute>
|
||
|
{
|
||
|
// This field is used to display errors messages to the user, if something goes wrong.
|
||
|
private string ErrorMessage;
|
||
|
|
||
|
// Reference to the method specified by the user in the attribute.
|
||
|
private MethodInfo Method;
|
||
|
|
||
|
protected override void Initialize()
|
||
|
{
|
||
|
// Use reflection to find the specified method, and store the method info in the context object.
|
||
|
this.Method = this.Property.ParentType.GetMethod(this.Attribute.MethodName, Flags.StaticInstanceAnyVisibility, null, Type.EmptyTypes, null);
|
||
|
|
||
|
if (this.Method == null)
|
||
|
{
|
||
|
this.ErrorMessage = "Could not find a parameterless method named '" + this.Attribute.MethodName + "' in the type '" + this.Property.ParentType + "'.";
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected override void DrawPropertyLayout(GUIContent label)
|
||
|
{
|
||
|
// Display any error that might have occured.
|
||
|
if (this.ErrorMessage != null)
|
||
|
{
|
||
|
SirenixEditorGUI.ErrorMessageBox(this.ErrorMessage);
|
||
|
|
||
|
// Continue drawing the rest of the property as normal.
|
||
|
this.CallNextDrawer(label);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Get the mouse down event.
|
||
|
bool clicked = Event.current.rawType == EventType.MouseDown && Event.current.button == 0 && this.Property.LastDrawnValueRect.Contains(Event.current.mousePosition);
|
||
|
|
||
|
if (clicked)
|
||
|
{
|
||
|
// Invoke the method stored in the context object.
|
||
|
if (this.Method.IsStatic)
|
||
|
{
|
||
|
this.Method.Invoke(null, null);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
this.Method.Invoke(this.Property.ParentValues[0], null);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Draw the property.
|
||
|
this.CallNextDrawer(label);
|
||
|
|
||
|
if (clicked)
|
||
|
{
|
||
|
// If the event havn't been used yet, then use it here.
|
||
|
Event.current.Use();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
}
|
||
|
#endif
|