forked from Shardstone/trail-into-darkness
95 lines
3.5 KiB
C#
95 lines
3.5 KiB
C#
using UnityEngine;
|
|
|
|
#if UNITY_EDITOR
|
|
using System.Reflection;
|
|
using UnityEditor;
|
|
using Jovian.InspectorTools.EditorTools;
|
|
#endif
|
|
|
|
namespace Jovian.InspectorTools {
|
|
/// <summary>
|
|
/// Does not work on objects with children - will break their UI
|
|
/// </summary>
|
|
public class RequireMethodAttribute : PropertyAttribute, IPropertyCondition {
|
|
|
|
private readonly string methodName;
|
|
|
|
public RequireMethodAttribute(string methodName) {
|
|
this.methodName = methodName;
|
|
}
|
|
|
|
#if UNITY_EDITOR
|
|
public bool DoesPropertyMeetCondition(SerializedProperty property, out string description) {
|
|
Object target = property.serializedObject.targetObject;
|
|
MethodInfo methodInfo = target.GetType().GetMethod(methodName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy);
|
|
description = string.Empty;
|
|
if (methodInfo != null && methodInfo.ReturnParameter?.ParameterType == typeof(bool)) {
|
|
ParameterInfo[] methodParameters = methodInfo.GetParameters();
|
|
|
|
object[] parameterValues = null;
|
|
if (methodParameters.Length == 1 && methodParameters[0].ParameterType == property.GetValue().GetType()) {
|
|
parameterValues = new[] { property.GetValue() };
|
|
}
|
|
|
|
object returnValue = methodInfo.Invoke(target, parameterValues);
|
|
if (returnValue is bool boolReturnValue) {
|
|
if (!boolReturnValue) {
|
|
description = $"{property.name} is failing {methodName}.";
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
else {
|
|
description = $"{property.name} {methodName} is invalid - does not return a boolean.";
|
|
return false;
|
|
}
|
|
}
|
|
|
|
description = $"{property.name} {methodName} is invalid - no method can be found on {target}.";
|
|
return false;
|
|
}
|
|
#endif
|
|
|
|
}
|
|
}
|
|
|
|
#if UNITY_EDITOR
|
|
namespace Jovian.InspectorTools.Internal {
|
|
[CustomPropertyDrawer(typeof(RequireMethodAttribute))]
|
|
public class RequireMethodAttributePropertyDrawer : PropertyDrawer {
|
|
|
|
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
|
|
RequireMethodAttribute requireMethodAttribute = (RequireMethodAttribute)attribute;
|
|
|
|
if (property.hasChildren) {
|
|
EditorGUI.LabelField(position, new GUIContent(property.displayName), new GUIContent("RequireMethod GUI does not work on properties with children"));
|
|
return;
|
|
}
|
|
|
|
Color guiColor = GUI.color;
|
|
|
|
if (!requireMethodAttribute.DoesPropertyMeetCondition(property, out string description)) {
|
|
RequiredUtil.LayoutRequired(ref position, description, false);
|
|
RequiredUtil.DrawRequired(ref position, description, false);
|
|
}
|
|
|
|
label = EditorGUI.BeginProperty(position, label, property);
|
|
position = EditorGUI.PrefixLabel(position, label);
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
|
|
EditorGUI.PropertyField(position, property, GUIContent.none);
|
|
|
|
if (EditorGUI.EndChangeCheck()) {
|
|
property.serializedObject.ApplyModifiedProperties();
|
|
}
|
|
|
|
EditorGUI.EndProperty();
|
|
|
|
GUI.color = guiColor;
|
|
}
|
|
|
|
}
|
|
}
|
|
#endif |