summaryrefslogtreecommitdiff
path: root/Assets/Plugins/AdvancedInspector/Core
diff options
context:
space:
mode:
Diffstat (limited to 'Assets/Plugins/AdvancedInspector/Core')
-rw-r--r--Assets/Plugins/AdvancedInspector/Core/ActionBinding.cs744
-rw-r--r--Assets/Plugins/AdvancedInspector/Core/ActionBinding.cs.meta8
-rw-r--r--Assets/Plugins/AdvancedInspector/Core/ComponentMonoBehaviour.cs199
-rw-r--r--Assets/Plugins/AdvancedInspector/Core/ComponentMonoBehaviour.cs.meta8
-rw-r--r--Assets/Plugins/AdvancedInspector/Core/RangeFloat.cs20
-rw-r--r--Assets/Plugins/AdvancedInspector/Core/RangeFloat.cs.meta8
-rw-r--r--Assets/Plugins/AdvancedInspector/Core/RangeInt.cs20
-rw-r--r--Assets/Plugins/AdvancedInspector/Core/RangeInt.cs.meta8
-rw-r--r--Assets/Plugins/AdvancedInspector/Core/UDictionary.cs230
-rw-r--r--Assets/Plugins/AdvancedInspector/Core/UDictionary.cs.meta8
10 files changed, 1253 insertions, 0 deletions
diff --git a/Assets/Plugins/AdvancedInspector/Core/ActionBinding.cs b/Assets/Plugins/AdvancedInspector/Core/ActionBinding.cs
new file mode 100644
index 00000000..55573bbd
--- /dev/null
+++ b/Assets/Plugins/AdvancedInspector/Core/ActionBinding.cs
@@ -0,0 +1,744 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+
+using UnityEngine;
+
+namespace AdvancedInspector
+{
+ /// <summary>
+ /// This class represent an event, and allows the Inspector to bind it to another method.
+ /// Arguments can be sent to the invoked method from a static field, internal from the code invoking, or from another method returned value.
+ /// </summary>
+ [Serializable, AdvancedInspector]
+ public class ActionBinding : ICopiable
+ {
+ [SerializeField]
+ private string[] internalParameters = new string[0];
+
+ [SerializeField]
+ private GameObject gameObject;
+
+ [Inspect]
+ public GameObject GameObject
+ {
+ get { return gameObject; }
+ set
+ {
+ if (gameObject != value)
+ {
+ gameObject = value;
+ Component = null;
+ }
+ }
+ }
+
+ [SerializeField]
+ private Component component;
+
+ [Inspect, Restrict("GetComponents")]
+ public Component Component
+ {
+ get { return component; }
+ set
+ {
+ if (component != value)
+ {
+ component = value;
+ Method = null;
+ }
+ }
+ }
+
+ private IList GetComponents()
+ {
+ List<DescriptorPair> components = new List<DescriptorPair>();
+ if (gameObject == null)
+ return components;
+
+ foreach (Component component in gameObject.GetComponents(typeof(Component)))
+ components.Add(new DescriptorPair(component, new DescriptorAttribute(component.GetType().Name, "")));
+
+ return components;
+ }
+
+ [SerializeField]
+ private string method;
+
+ [Inspect, Restrict("GetMethods", RestrictDisplay.Toolbox)]
+ public MethodInfo Method
+ {
+ get { return GetMethodInfo(); }
+ set
+ {
+ if (value == null)
+ {
+ parameters = new BindingParameter[0];
+ method = "";
+ return;
+ }
+
+ MethodInfo info = GetMethodInfo();
+ if (info != value)
+ {
+ method = value.Name;
+ ParameterInfo[] param = value.GetParameters();
+ parameters = new BindingParameter[param.Length];
+ for (int i = 0; i < param.Length; i++)
+ {
+ parameters[i] = new BindingParameter(internalParameters.Length > i);
+ parameters[i].Type = param[i].ParameterType;
+ if (internalParameters.Length > i)
+ parameters[i].binding = BindingParameter.BindingType.Internal;
+ }
+ }
+ }
+ }
+
+ private IList GetMethods()
+ {
+ List<DescriptorPair> methods = new List<DescriptorPair>();
+ if (gameObject == null || component == null)
+ return methods;
+
+ foreach (MethodInfo info in component.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy))
+ {
+ if (info.IsGenericMethod || info.IsConstructor || info.IsFinal || info.IsSpecialName || info.DeclaringType == typeof(object) || info.DeclaringType == typeof(Component))
+ continue;
+
+ if (!IsMethodValid(info))
+ continue;
+
+ ParameterInfo[] param = info.GetParameters();
+
+ methods.Add(new DescriptorPair(info, new DescriptorAttribute(GetParamNames(info.Name, param), "")));
+ }
+
+ foreach (PropertyInfo info in component.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy))
+ {
+ if (!info.CanWrite || info.DeclaringType == typeof(object) || info.DeclaringType == typeof(UnityEngine.Object) || info.DeclaringType == typeof(Component))
+ continue;
+
+ MethodInfo method = info.GetSetMethod();
+ if (method == null || !IsMethodValid(method))
+ continue;
+
+ ParameterInfo[] param = method.GetParameters();
+
+ methods.Add(new DescriptorPair(method, new DescriptorAttribute(GetParamNames(info.Name, param), "")));
+ }
+
+ return methods;
+ }
+
+ private bool IsMethodValid(MethodInfo info)
+ {
+ ParameterInfo[] param = info.GetParameters();
+
+ bool valid = true;
+ for (int i = 0; i < param.Length; i++)
+ {
+ if (!BindingParameter.IsValidType(param[i].ParameterType))
+ {
+ valid = false;
+ break;
+ }
+
+ if (internalParameters.Length > i)
+ {
+ Type type = Type.GetType(internalParameters[i]);
+ if (!type.IsAssignableFrom(param[i].ParameterType))
+ {
+ valid = false;
+ break;
+ }
+ }
+ }
+
+ return valid;
+ }
+
+ private string GetParamNames(string name, ParameterInfo[] param)
+ {
+ string paramName = name + " (";
+ for (int i = 0; i < param.Length; i++)
+ {
+ paramName += param[i].ParameterType.Name;
+ if (i < param.Length - 1)
+ paramName += ", ";
+ }
+ paramName += ")";
+
+ return paramName;
+ }
+
+ private MethodInfo GetMethodInfo()
+ {
+ if (gameObject == null || component == null || string.IsNullOrEmpty(method))
+ return null;
+
+ Type[] types = new Type[parameters.Length];
+ for (int i = 0; i < parameters.Length; i++)
+ types[i] = parameters[i].Type;
+
+ return component.GetType().GetMethod(method, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy, null, types, null);
+ }
+
+ [Inspect, Collection(0, false), SerializeField]
+ private BindingParameter[] parameters = new BindingParameter[0];
+
+ public event ActionEventHandler OnInvoke;
+
+ /// <summary>
+ /// Parameter-less method constructor.
+ /// </summary>
+ public ActionBinding() { }
+
+ /// <summary>
+ /// The array of types is the method definition.
+ /// Method with the wrong parameters are not selectable.
+ /// </summary>
+ public ActionBinding(Type[] types)
+ {
+ internalParameters = new string[types.Length];
+ for (int i = 0; i < types.Length; i++)
+ internalParameters[i] = types[i].AssemblyQualifiedName;
+ }
+
+ /// <summary>
+ /// Invoke the method.
+ /// Be careful to pass the proper type as args, otherwise they will be ignored.
+ /// Args are only retained if the parameter is flagged as internal.
+ /// </summary>
+ public void Invoke(params object[] args)
+ {
+ if (gameObject == null || component == null || string.IsNullOrEmpty(method))
+ return;
+
+ MethodInfo info = GetMethodInfo();
+ if (info == null)
+ return;
+
+ object[] values = new object[parameters.Length];
+ for (int i = 0; i < parameters.Length; i++)
+ {
+ if (args.Length > i && parameters[i].binding == BindingParameter.BindingType.Internal)
+ values[i] = args[i];
+ else
+ values[i] = parameters[i].Value;
+ }
+
+ info.Invoke(component, values);
+
+ if (OnInvoke != null)
+ OnInvoke(this, values);
+ }
+
+ public override string ToString()
+ {
+ string supplied = "(";
+ for (int i = 0; i < internalParameters.Length; i++)
+ {
+ supplied += Type.GetType(internalParameters[i]).Name;
+ if (i < internalParameters.Length - 1)
+ supplied += ", ";
+ }
+
+ supplied += ")";
+
+ if (component != null)
+ return component.GetType().Name + " : " + method + " : " + supplied;
+ else
+ return supplied;
+ }
+
+ public bool Copiable(object destination)
+ {
+ ActionBinding action = destination as ActionBinding;
+ if (action == null)
+ return false;
+
+ if (action.internalParameters.Length != internalParameters.Length)
+ return false;
+
+ for (int i = 0; i < internalParameters.Length; i++)
+ if (internalParameters[i] != action.internalParameters[i])
+ return false;
+
+ return true;
+ }
+
+ /// <summary>
+ /// The binding parameter define how each of the argument of the invoked method is handled.
+ /// </summary>
+ [Serializable, AdvancedInspector]
+ public class BindingParameter : ICopy, ICopiable
+ {
+ [Inspect(-1), Restrict("RestrictBinding")]
+ public BindingType binding;
+
+ private IList RestrictBinding()
+ {
+ List<object> list = new List<object>();
+ if (canBeInternal)
+ list.Add(BindingType.Internal);
+
+ list.Add(BindingType.Static);
+ list.Add(BindingType.External);
+ return list;
+ }
+
+ private bool canBeInternal = true;
+
+ private bool CanBeInternal
+ {
+ get { return canBeInternal; }
+ }
+
+ #region Values
+ [SerializeField]
+ private BindingValueType type;
+
+ [SerializeField]
+ private string qualifiedTypeName;
+
+ public Type Type
+ {
+ get
+ {
+ if (string.IsNullOrEmpty(qualifiedTypeName))
+ return null;
+ else
+ return Type.GetType(qualifiedTypeName);
+ }
+
+ set
+ {
+ if (value == typeof(bool))
+ type = BindingValueType.Boolean;
+ else if (value == typeof(Bounds))
+ type = BindingValueType.Bounds;
+ else if (value == typeof(Color))
+ type = BindingValueType.Color;
+ else if (value == typeof(float))
+ type = BindingValueType.Float;
+ else if (value == typeof(int))
+ type = BindingValueType.Integer;
+ else if (value == typeof(Rect))
+ type = BindingValueType.Rect;
+ else if (typeof(UnityEngine.Object).IsAssignableFrom(value))
+ type = BindingValueType.Reference;
+ else if (value == typeof(string))
+ type = BindingValueType.String;
+ else if (value == typeof(Vector2))
+ type = BindingValueType.Vector2;
+ else if (value == typeof(Vector3))
+ type = BindingValueType.Vector3;
+ else if (value == typeof(Vector4))
+ type = BindingValueType.Vector4;
+ else
+ type = BindingValueType.None;
+
+ if (type != BindingValueType.None)
+ qualifiedTypeName = value.AssemblyQualifiedName;
+ else
+ qualifiedTypeName = "";
+ }
+ }
+
+ [Inspect(-2)]
+ public string BoundType
+ {
+ get
+ {
+ if (Type == null)
+ return "";
+
+ return Type.Name;
+ }
+ }
+
+ [SerializeField]
+ private bool boolValue = false;
+ [SerializeField]
+ private int intValue = 0;
+ [SerializeField]
+ private float floatValue = 0;
+ [SerializeField]
+ private string stringValue = "";
+ [SerializeField]
+ private Vector2 vector2Value = Vector2.zero;
+ [SerializeField]
+ private Vector3 vector3Value = Vector3.zero;
+ [SerializeField]
+ private Vector4 vector4Value = Vector4.zero;
+ [SerializeField]
+ private Color colorValue = Color.black;
+ [SerializeField]
+ private Rect rectValue = new Rect(0, 0, 0, 0);
+ [SerializeField]
+ private Bounds boundsValue = new Bounds(Vector3.zero, Vector3.zero);
+ [SerializeField]
+ private UnityEngine.Object referenceValue = new UnityEngine.Object();
+ #endregion
+
+ [Inspect("IsStatic")]
+ [RuntimeResolve("GetRuntimeType")]
+ public object Value
+ {
+ get
+ {
+ if (binding == BindingType.External)
+ {
+ object value = Invoke();
+ if (value.GetType().IsAssignableFrom(Type))
+ return value;
+
+ System.ComponentModel.TypeConverter converter = System.ComponentModel.TypeDescriptor.GetConverter(Type);
+ return converter.ConvertTo(value, Type);
+ }
+
+ switch (type)
+ {
+ case BindingValueType.Boolean:
+ return boolValue;
+ case BindingValueType.Bounds:
+ return boundsValue;
+ case BindingValueType.Color:
+ return colorValue;
+ case BindingValueType.Float:
+ return floatValue;
+ case BindingValueType.Integer:
+ return intValue;
+ case BindingValueType.Rect:
+ return rectValue;
+ case BindingValueType.Reference:
+ return referenceValue;
+ case BindingValueType.String:
+ return stringValue;
+ case BindingValueType.Vector2:
+ return vector2Value;
+ case BindingValueType.Vector3:
+ return vector3Value;
+ case BindingValueType.Vector4:
+ return vector4Value;
+ default:
+ return null;
+ }
+ }
+
+ set
+ {
+ if (value == null && type != BindingValueType.Reference)
+ return;
+
+ switch (type)
+ {
+ case BindingValueType.Boolean:
+ boolValue = (bool)value;
+ break;
+ case BindingValueType.Bounds:
+ boundsValue = (Bounds)value;
+ break;
+ case BindingValueType.Color:
+ colorValue = (Color)value;
+ break;
+ case BindingValueType.Float:
+ floatValue = (float)value;
+ break;
+ case BindingValueType.Integer:
+ intValue = (int)value;
+ break;
+ case BindingValueType.Rect:
+ rectValue = (Rect)value;
+ break;
+ case BindingValueType.Reference:
+ referenceValue = (UnityEngine.Object)value;
+ break;
+ case BindingValueType.String:
+ stringValue = (string)value;
+ break;
+ case BindingValueType.Vector2:
+ vector2Value = (Vector2)value;
+ break;
+ case BindingValueType.Vector3:
+ vector3Value = (Vector3)value;
+ break;
+ case BindingValueType.Vector4:
+ vector4Value = (Vector4)value;
+ break;
+ default:
+ return;
+ }
+ }
+ }
+
+ [SerializeField]
+ private GameObject gameObject;
+
+ [Inspect("IsExternal")]
+ public GameObject GameObject
+ {
+ get { return gameObject; }
+ set
+ {
+ if (gameObject != value)
+ {
+ gameObject = value;
+ Component = null;
+ }
+ }
+ }
+
+ [SerializeField]
+ private Component component;
+
+ [Inspect("IsExternal")]
+ [Restrict("GetComponents")]
+ public Component Component
+ {
+ get { return component; }
+ set
+ {
+ if (component != value)
+ {
+ component = value;
+ Method = null;
+ }
+ }
+ }
+
+ private IList GetComponents()
+ {
+ List<DescriptorPair> components = new List<DescriptorPair>();
+ if (gameObject == null)
+ return components;
+
+ foreach (Component component in gameObject.GetComponents(typeof(Component)))
+ components.Add(new DescriptorPair(component, new DescriptorAttribute(component.GetType().Name, "")));
+
+ return components;
+ }
+
+ [SerializeField]
+ private string method;
+
+ [Inspect("IsExternal")]
+ [Restrict("GetMethods", RestrictDisplay.Toolbox)]
+ public MethodInfo Method
+ {
+ get { return GetMethodInfo(); }
+ set
+ {
+ if (value == null)
+ {
+ method = "";
+ return;
+ }
+
+ MethodInfo info = GetMethodInfo();
+ if (info != value)
+ method = value.Name;
+ }
+ }
+
+ private IList GetMethods()
+ {
+ List<DescriptorPair> methods = new List<DescriptorPair>();
+ if (gameObject == null || component == null)
+ return methods;
+
+ foreach (MethodInfo info in component.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy))
+ {
+ if (info.IsGenericMethod || info.IsConstructor || info.IsFinal || info.IsSpecialName)
+ continue;
+
+ if (!IsMethodValid(info))
+ continue;
+
+ string paramName = info.ReturnType.Name + " " + info.Name + "()";
+ methods.Add(new DescriptorPair(info, new DescriptorAttribute(paramName, "")));
+ }
+
+ foreach (PropertyInfo info in component.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy))
+ {
+ if (!info.CanRead)
+ continue;
+
+ MethodInfo method = info.GetGetMethod();
+ if (method == null || !IsMethodValid(method))
+ continue;
+
+ string paramName = method.ReturnType.Name + " " + info.Name + "()";
+ methods.Add(new DescriptorPair(method, new DescriptorAttribute(paramName, "")));
+ }
+
+ return methods;
+ }
+
+ private bool IsMethodValid(MethodInfo info)
+ {
+ ParameterInfo[] param = info.GetParameters();
+ if (param.Length > 0)
+ return false;
+
+ if (info.ReturnType == null || info.ReturnType == typeof(void))
+ return false;
+
+ System.ComponentModel.TypeConverter converter = System.ComponentModel.TypeDescriptor.GetConverter(info.ReturnType);
+ if (!Type.IsAssignableFrom(info.ReturnType) && !converter.CanConvertTo(Type))
+ return false;
+
+ return true;
+ }
+
+ private MethodInfo GetMethodInfo()
+ {
+ if (gameObject == null || component == null || string.IsNullOrEmpty(method))
+ return null;
+
+ return component.GetType().GetMethod(method, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy);
+ }
+
+ private bool IsStatic()
+ {
+ return binding == BindingType.Static;
+ }
+
+ private bool IsExternal()
+ {
+ return binding == BindingType.External;
+ }
+
+ private Type GetRuntimeType()
+ {
+ return Type;
+ }
+
+ public BindingParameter() { }
+
+ public BindingParameter(bool canBeInternal)
+ {
+ this.canBeInternal = canBeInternal;
+ }
+
+ public static bool IsValidType(Type type)
+ {
+ if (type == typeof(bool))
+ return true;
+ else if (type == typeof(Bounds))
+ return true;
+ else if (type == typeof(Color))
+ return true;
+ else if (type == typeof(float))
+ return true;
+ else if (type == typeof(int))
+ return true;
+ else if (type == typeof(Rect))
+ return true;
+ else if (typeof(UnityEngine.Object).IsAssignableFrom(type))
+ return true;
+ else if (type == typeof(string))
+ return true;
+ else if (type == typeof(Vector2))
+ return true;
+ else if (type == typeof(Vector3))
+ return true;
+ else if (type == typeof(Vector4))
+ return true;
+
+ return false;
+ }
+
+ public enum BindingType
+ {
+ Internal,
+ Static,
+ External
+ }
+
+ private enum BindingValueType
+ {
+ None,
+
+ Boolean,
+ Integer,
+ Float,
+ String,
+ Vector2,
+ Vector3,
+ Vector4,
+ Color,
+ Rect,
+ Bounds,
+ Reference
+ }
+
+ private object Invoke()
+ {
+ if (gameObject == null || component == null || string.IsNullOrEmpty(method))
+ return null;
+
+ MethodInfo info = GetMethodInfo();
+ if (info == null)
+ return null;
+
+ return info.Invoke(component, new object[0]);
+ }
+
+ public bool Copiable(object destination)
+ {
+ BindingParameter target = destination as BindingParameter;
+ if (target == null)
+ return false;
+
+ if (target.type != type)
+ return false;
+
+ if (!target.canBeInternal && binding == BindingType.Internal)
+ return false;
+
+ return true;
+ }
+
+ public object Copy(object destination)
+ {
+ BindingParameter target = destination as BindingParameter;
+
+ BindingParameter copy = new BindingParameter();
+ if (target != null)
+ copy.canBeInternal = target.canBeInternal;
+ else
+ copy.canBeInternal = canBeInternal;
+
+ copy.binding = binding;
+ copy.boolValue = boolValue;
+ copy.boundsValue = boundsValue;
+ copy.colorValue = colorValue;
+ copy.component = component;
+ copy.floatValue = floatValue;
+ copy.gameObject = gameObject;
+ copy.intValue = intValue;
+ copy.method = method;
+ copy.qualifiedTypeName = qualifiedTypeName;
+ copy.rectValue = rectValue;
+ copy.referenceValue = referenceValue;
+ copy.stringValue = stringValue;
+ copy.type = type;
+ copy.vector2Value = vector2Value;
+ copy.vector3Value = vector3Value;
+ copy.vector4Value = vector4Value;
+
+ return copy;
+ }
+
+ public override string ToString()
+ {
+ return type.ToString();
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/Assets/Plugins/AdvancedInspector/Core/ActionBinding.cs.meta b/Assets/Plugins/AdvancedInspector/Core/ActionBinding.cs.meta
new file mode 100644
index 00000000..1b2c79dc
--- /dev/null
+++ b/Assets/Plugins/AdvancedInspector/Core/ActionBinding.cs.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 3dda590f8ffeb5848b2e6775c1caa63a
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/Assets/Plugins/AdvancedInspector/Core/ComponentMonoBehaviour.cs b/Assets/Plugins/AdvancedInspector/Core/ComponentMonoBehaviour.cs
new file mode 100644
index 00000000..e5d04884
--- /dev/null
+++ b/Assets/Plugins/AdvancedInspector/Core/ComponentMonoBehaviour.cs
@@ -0,0 +1,199 @@
+using UnityEngine;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+
+namespace AdvancedInspector
+{
+ /// <summary>
+ /// ScriptableObject are not serializable within the scope of a GameObject.
+ /// Therefore, they are improper to prefab, copy and so on.
+ /// This class' goal is to provide a polymorphic solution and give an easy way of handling up front.
+ ///
+ /// Derived from Object; no polymorphism supported.
+ /// Derived from ScriptableObject; cannot be prefabed, copied, duplicated or instanced.
+ /// Derived from MonoBehaviour; can only live on a GameObject.
+ ///
+ /// A ComponentMonoBehaviour is created from another MonoBehaviour; its parent.
+ /// A parent can be another ComponentMonoBehaviour.
+ /// If the parent is destroyed, the subcomponent is destroyed too.
+ /// If a subcomponent is found without a parent, it's destroyed too.
+ /// </summary>
+ [AdvancedInspector]
+ public abstract class ComponentMonoBehaviour : MonoBehaviour
+ {
+ [SerializeField]
+ private MonoBehaviour owner;
+
+ /// <summary>
+ /// The owner of a "subcomponent".
+ /// Use to know if this component lost its parent.
+ /// If so, the AdvancedInspector will delete any unused component.
+ /// </summary>
+ public MonoBehaviour Owner
+ {
+ get { return owner; }
+ set
+ {
+ if (value != null)
+ owner = value;
+ }
+ }
+
+ /// <summary>
+ /// A subcomponent is not visible the normal way in the Inspector.
+ /// It's shown as being part of another item.
+ /// </summary>
+ protected virtual void Reset()
+ {
+ hideFlags = HideFlags.HideInInspector;
+ }
+
+ /// <summary>
+ /// Called when the inspector is about to destroy this one.
+ /// Loop in all the internal and destroy sub-components.
+ /// </summary>
+ public void Erase()
+ {
+ foreach (FieldInfo info in GetFields(GetType(), false))
+ {
+ object value = info.GetValue(this);
+
+ if (value is ComponentMonoBehaviour)
+ {
+ ComponentMonoBehaviour component = value as ComponentMonoBehaviour;
+
+ if (component.Owner == Owner)
+ component.Erase();
+ }
+ }
+
+ DestroyImmediate(this, true);
+ }
+
+ /// <summary>
+ /// Instanciate an existing Component on the same owner GameObject
+ /// </summary>
+ public ComponentMonoBehaviour Instantiate()
+ {
+ return Instantiate(gameObject, Owner);
+ }
+
+ /// <summary>
+ /// Instanciate an existing Component on the same owner GameObject but with a new onwer.
+ /// </summary>
+ public ComponentMonoBehaviour Instantiate(MonoBehaviour owner)
+ {
+ return Instantiate(gameObject, owner);
+ }
+
+ /// <summary>
+ /// Instanciate an existing Component on the target GameObject.
+ /// </summary>
+ public ComponentMonoBehaviour Instantiate(GameObject go, MonoBehaviour owner)
+ {
+ return CopyObject(go, owner, this) as ComponentMonoBehaviour;
+ }
+
+ private static object CopyObject(GameObject go, MonoBehaviour owner, object original)
+ {
+ if (original == null)
+ return null;
+
+ Type type = original.GetType();
+
+ if (type == typeof(string))
+
+ return ((string)original).Clone();
+ else if (type.Namespace == "System")
+ return original;
+ else if (typeof(IList).IsAssignableFrom(type))
+ return CopyList(go, owner, (IList)original);
+ else if (typeof(ComponentMonoBehaviour).IsAssignableFrom(type) && ((ComponentMonoBehaviour)original).Owner == owner)
+ return CopyComponent(go, owner, (ComponentMonoBehaviour)original);
+ else if (typeof(Component).IsAssignableFrom(type))
+ return original;
+ else if (typeof(ScriptableObject).IsAssignableFrom(type))
+ return ScriptableObject.Instantiate((ScriptableObject)original);
+ else if (typeof(UnityEngine.Object).IsAssignableFrom(type))
+ return original;
+ else if (type.IsClass)
+ return CopyClass(go, owner, original);
+ else
+ return original;
+ }
+
+ private static IList CopyList(GameObject go, MonoBehaviour owner, IList original)
+ {
+ Type type = original.GetType();
+ IList copy;
+
+ if (type.IsArray)
+ {
+ copy = Array.CreateInstance(type.GetElementType(), original.Count);
+ for (int i = 0; i < original.Count; i++)
+ copy[i] = CopyObject(go, owner, original[i]);
+ }
+ else
+ {
+ copy = Activator.CreateInstance(type) as IList;
+ for (int i = 0; i < original.Count; i++)
+ copy.Add(CopyObject(go, owner, original[i]));
+
+ }
+
+ return copy;
+ }
+
+ private static ComponentMonoBehaviour CopyComponent(GameObject go, MonoBehaviour owner, ComponentMonoBehaviour original)
+ {
+ Type type = original.GetType();
+ ComponentMonoBehaviour copy = go.AddComponent(original.GetType()) as ComponentMonoBehaviour;
+
+ foreach (FieldInfo info in GetFields(type, false))
+ {
+ if (info.IsLiteral)
+ continue;
+
+ info.SetValue(copy, CopyObject(go, copy, info.GetValue(original)));
+ }
+
+ copy.Owner = owner;
+
+ return copy;
+ }
+
+ private static object CopyClass(GameObject go, MonoBehaviour owner, object original)
+ {
+ Type type = original.GetType();
+ object copy = Activator.CreateInstance(type);
+
+ foreach (FieldInfo info in GetFields(type, false))
+ {
+ if (info.IsLiteral)
+ continue;
+
+ info.SetValue(copy, CopyObject(go, owner, info.GetValue(original)));
+ }
+
+ return copy;
+ }
+
+ private static List<FieldInfo> GetFields(Type type, bool recursive)
+ {
+ List<FieldInfo> infos;
+
+ if (recursive)
+ infos = type.GetFields(BindingFlags.NonPublic | BindingFlags.Instance).ToList();
+ else
+ infos = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy).ToList();
+
+ if (type.BaseType != null && type.BaseType != typeof(object))
+ infos.AddRange(GetFields(type.BaseType, true));
+
+ return infos;
+ }
+ }
+} \ No newline at end of file
diff --git a/Assets/Plugins/AdvancedInspector/Core/ComponentMonoBehaviour.cs.meta b/Assets/Plugins/AdvancedInspector/Core/ComponentMonoBehaviour.cs.meta
new file mode 100644
index 00000000..d987b370
--- /dev/null
+++ b/Assets/Plugins/AdvancedInspector/Core/ComponentMonoBehaviour.cs.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: d411934b81db62841acf60342a15b9c3
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/Assets/Plugins/AdvancedInspector/Core/RangeFloat.cs b/Assets/Plugins/AdvancedInspector/Core/RangeFloat.cs
new file mode 100644
index 00000000..f7442db6
--- /dev/null
+++ b/Assets/Plugins/AdvancedInspector/Core/RangeFloat.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace AdvancedInspector
+{
+ [Serializable]
+ public struct RangeFloat
+ {
+ public float min;
+ public float max;
+
+ public RangeFloat(float min, float max)
+ {
+ this.min = min;
+ this.max = max;
+ }
+ }
+} \ No newline at end of file
diff --git a/Assets/Plugins/AdvancedInspector/Core/RangeFloat.cs.meta b/Assets/Plugins/AdvancedInspector/Core/RangeFloat.cs.meta
new file mode 100644
index 00000000..a2c19ce3
--- /dev/null
+++ b/Assets/Plugins/AdvancedInspector/Core/RangeFloat.cs.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: bee2349f549bbc341bd8f823cb45ccbf
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/Assets/Plugins/AdvancedInspector/Core/RangeInt.cs b/Assets/Plugins/AdvancedInspector/Core/RangeInt.cs
new file mode 100644
index 00000000..bfe55c58
--- /dev/null
+++ b/Assets/Plugins/AdvancedInspector/Core/RangeInt.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace AdvancedInspector
+{
+ [Serializable]
+ public struct RangeInt
+ {
+ public int min;
+ public int max;
+
+ public RangeInt(int min, int max)
+ {
+ this.min = min;
+ this.max = max;
+ }
+ }
+} \ No newline at end of file
diff --git a/Assets/Plugins/AdvancedInspector/Core/RangeInt.cs.meta b/Assets/Plugins/AdvancedInspector/Core/RangeInt.cs.meta
new file mode 100644
index 00000000..3b73338c
--- /dev/null
+++ b/Assets/Plugins/AdvancedInspector/Core/RangeInt.cs.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 6c92ce2aa7de2a7438784b0cc719f9ac
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/Assets/Plugins/AdvancedInspector/Core/UDictionary.cs b/Assets/Plugins/AdvancedInspector/Core/UDictionary.cs
new file mode 100644
index 00000000..5322154f
--- /dev/null
+++ b/Assets/Plugins/AdvancedInspector/Core/UDictionary.cs
@@ -0,0 +1,230 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Runtime.Serialization;
+using System.Text;
+
+using UnityEngine;
+
+namespace AdvancedInspector
+{
+ [Serializable]
+ [ComVisible(false)]
+ [DebuggerDisplay("Count = {Count}")]
+ public class UDictionary<TKey, TValue> : IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IDictionary, ICollection, IEnumerable, ISerializable, IDeserializationCallback, ISerializationCallbackReceiver
+ {
+ [SerializeField]
+ private List<TKey> keys = new List<TKey>();
+
+ [SerializeField]
+ private List<TValue> values = new List<TValue>();
+
+ [NonSerialized]
+ private Dictionary<TKey, TValue> dictionary = new Dictionary<TKey, TValue>();
+
+ #region Implementation of ISerializationCallbackReceiver
+ public void OnAfterDeserialize()
+ {
+ dictionary.Clear();
+ for (int i = 0; i < keys.Count; i++)
+ if (keys[i] != null && (!(keys[i] is UnityEngine.Object) || ((UnityEngine.Object)(object)keys[i])))
+ dictionary.Add(keys[i], values[i]);
+ }
+
+ public void OnBeforeSerialize()
+ {
+ keys.Clear();
+ values.Clear();
+ foreach (KeyValuePair<TKey, TValue> pair in dictionary)
+ {
+ if (pair.Key == null || (pair.Key is UnityEngine.Object && !((UnityEngine.Object)(object)pair.Key)))
+ continue;
+
+ keys.Add(pair.Key);
+ values.Add(pair.Value);
+ }
+ }
+ #endregion
+
+ #region Implementation of ISerializable
+ public void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ dictionary.GetObjectData(info, context);
+ }
+ #endregion
+
+ #region Implementation of IDeserializationCallback
+ public void OnDeserialization(object sender)
+ {
+ dictionary.OnDeserialization(sender);
+ }
+ #endregion
+
+ #region Implementation IDictionary
+ public bool IsFixedSize
+ {
+ get { return false; }
+ }
+
+ public ICollection<TKey> Keys
+ {
+ get { return dictionary.Keys; }
+ }
+
+ ICollection IDictionary.Keys
+ {
+ get { return dictionary.Keys; }
+ }
+
+ public ICollection<TValue> Values
+ {
+ get { return dictionary.Values; }
+ }
+
+ ICollection IDictionary.Values
+ {
+ get { return dictionary.Values; }
+ }
+
+ public TValue this[TKey key]
+ {
+ get { return dictionary[key]; }
+ set { dictionary[key] = value; }
+ }
+
+ object IDictionary.this[object key]
+ {
+ get
+ {
+ if (!(key is TKey))
+ return null;
+
+ return dictionary[(TKey)key];
+ }
+ set
+ {
+ if (!(key is TKey))
+ return;
+
+ if (!(value is TValue) && value != null)
+ return;
+
+ dictionary[(TKey)key] = (TValue)value;
+ }
+ }
+
+ public void Add(TKey key, TValue value)
+ {
+ dictionary.Add(key, value);
+ }
+
+ void IDictionary.Add(object key, object value)
+ {
+ if (!(key is TKey))
+ return;
+
+ if (!(value is TValue) && value != null)
+ return;
+
+ dictionary.Add((TKey)key, (TValue)value);
+ }
+
+ public bool ContainsKey(TKey key)
+ {
+ return dictionary.ContainsKey(key);
+ }
+
+ bool IDictionary.Contains(object key)
+ {
+ if (!(key is TKey))
+ return false;
+
+ return dictionary.ContainsKey((TKey)key);
+ }
+
+ public bool Remove(TKey key)
+ {
+ return dictionary.Remove(key);
+ }
+
+ void IDictionary.Remove(object key)
+ {
+ if (!(key is TKey))
+ return;
+
+ dictionary.Remove((TKey)key);
+ }
+
+ public bool TryGetValue(TKey key, out TValue value)
+ {
+ return dictionary.TryGetValue(key, out value);
+ }
+
+ IDictionaryEnumerator IDictionary.GetEnumerator()
+ {
+ return ((IDictionary)dictionary).GetEnumerator();
+ }
+ #endregion
+
+ #region Implementation ICollection
+ public int Count
+ {
+ get { return dictionary.Count; }
+ }
+
+ public bool IsReadOnly
+ {
+ get { return false; }
+ }
+
+ public bool IsSynchronized
+ {
+ get { return false; }
+ }
+
+ public object SyncRoot
+ {
+ get { return null; }
+ }
+
+ public void Add(KeyValuePair<TKey, TValue> item)
+ {
+ dictionary.Add(item.Key, item.Value);
+ }
+
+ public void Clear()
+ {
+ dictionary.Clear();
+ }
+
+ public bool Contains(KeyValuePair<TKey, TValue> item)
+ {
+ return dictionary.ContainsKey(item.Key) && dictionary[item.Key].Equals(item.Value);
+ }
+
+ void ICollection.CopyTo(Array array, int index) { }
+
+ void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex) { }
+
+ public bool Remove(KeyValuePair<TKey, TValue> item)
+ {
+ return dictionary.Remove(item.Key);
+ }
+ #endregion
+
+ #region Implementation of IEnumerable
+ public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
+ {
+ return dictionary.GetEnumerator();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return dictionary.GetEnumerator();
+ }
+ #endregion
+ }
+} \ No newline at end of file
diff --git a/Assets/Plugins/AdvancedInspector/Core/UDictionary.cs.meta b/Assets/Plugins/AdvancedInspector/Core/UDictionary.cs.meta
new file mode 100644
index 00000000..f39539f9
--- /dev/null
+++ b/Assets/Plugins/AdvancedInspector/Core/UDictionary.cs.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 9e2fe3e177768eb42ac8308f4f3e3c6a
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData: