using System; using System.Reflection; using System.Collections.Generic; using UnityEngine; namespace AdvancedInspector { /// /// Makes a property viewable in the Inspector of Unity. /// Turns a method into a button in the Inspector. /// You can input a conditional statement for your property to show up or not. /// [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Method)] public class InspectAttribute : Attribute, IRuntimeAttribute { public delegate bool InspectDelegate(); public delegate bool InspectStaticDelegate(InspectAttribute inspect, object instance, object value); private InspectorLevel level; /// /// Inspector level are use to hide more advanced item. /// Items under the current Inspector levels are hidden. /// public InspectorLevel Level { get { return level; } set { level = value; } } private bool condition = true; /// /// Inverse the condition used by the IRuntime method. /// public bool Condition { get { return condition; } set { condition = value; } } private int priority = 0; /// /// Priority of display of this item. /// Smaller values are displayed first. Negative value are supported. /// public int Priority { get { return priority; } set { priority = value; } } #region IRuntime Implementation private string methodName = ""; public string MethodName { get { return methodName; } set { methodName = value; } } public Type Template { get { return typeof(InspectDelegate); } } public Type TemplateStatic { get { return typeof(InspectStaticDelegate); } } private List delegates = new List(); public List Delegates { get { return delegates; } set { delegates = value; } } public bool Invoke(int index, object instance, object value) { if (delegates.Count == 0 || index >= delegates.Count) return true; try { if (delegates[index].Target == null) { if (condition) return (bool)delegates[index].DynamicInvoke(this, instance, value); else return !(bool)delegates[index].DynamicInvoke(this, instance, value); } else { if (condition) return (bool)delegates[index].DynamicInvoke(); else return !(bool)delegates[index].DynamicInvoke(); } } catch (Exception e) { if (e is TargetInvocationException) e = ((TargetInvocationException)e).InnerException; Debug.LogError(string.Format("Invoking a method to retrieve a Inspect attribute failed. The exception was \"{0}\".", e.Message)); return true; } } #endregion #region Compile Time Constructor public InspectAttribute() : this(InspectorLevel.Basic, "", true, 0) { } public InspectAttribute(int priority) : this(InspectorLevel.Basic, "", true, priority) { } public InspectAttribute(InspectorLevel level) : this(level, "", true, 0) { } public InspectAttribute(InspectorLevel level, int priority) : this(level, "", true, priority) { } public InspectAttribute(InspectorLevel level, string methodName) : this(level, methodName, true, 0) { } public InspectAttribute(InspectorLevel level, string methodName, int priority) : this(level, methodName, true, priority) { } public InspectAttribute(InspectorLevel level, string methodName, bool condition) : this(level, methodName, condition, 0) { } public InspectAttribute(string methodName) : this(InspectorLevel.Basic, methodName, true, 0) { } public InspectAttribute(string methodName, int priority) : this(InspectorLevel.Basic, methodName, true, priority) { } public InspectAttribute(string methodName, bool condition) : this(InspectorLevel.Basic, methodName, condition, 0) { } public InspectAttribute(string methodName, bool condition, int priority) : this(InspectorLevel.Basic, methodName, condition, priority) { } public InspectAttribute(InspectorLevel level, string methodName, bool condition, int priority) { this.level = level; this.condition = condition; this.methodName = methodName; this.priority = priority; } #endregion #region Runtime Constructor public InspectAttribute(Delegate method) : this(InspectorLevel.Basic, method, true, 0) { } public InspectAttribute(Delegate method, int priority) : this(InspectorLevel.Basic, method, true, priority) { } public InspectAttribute(Delegate method, bool condition) : this(InspectorLevel.Basic, method, condition, 0) { } public InspectAttribute(Delegate method, bool condition, int priority) : this(InspectorLevel.Basic, method, condition, priority) { } public InspectAttribute(InspectorLevel level, Delegate method) : this(level, method, true, 0) { } public InspectAttribute(InspectorLevel level, Delegate method, int priority) : this(level, method, true, priority) { } public InspectAttribute(InspectorLevel level, Delegate method, bool condition, int priority) { this.level = level; this.condition = condition; this.priority = priority; this.delegates.Add(method); } #endregion } /// /// You can change or add your own levels. /// public enum InspectorLevel { Basic = 0, Advanced = 1, Debug = 2 } }