using UnityEngine; using UnityEditor; using System; using System.Collections; using System.Collections.Generic; using System.Reflection; using System.Linq; namespace KairoEngine.Core { /// /// Custom attributes /// [AttributeUsage(AttributeTargets.Field | AttributeTargets.Class, AllowMultiple = true)] public class HideInspectorDerived : Attribute { public readonly Type m_derivedtype; public readonly string m_fieldname; public HideInspectorDerived(Type derivedtype) // Hide from specific derived type { m_derivedtype = derivedtype; m_fieldname = ""; } public HideInspectorDerived() // Hide from all descendants { m_derivedtype = null; m_fieldname = ""; } public HideInspectorDerived(string fieldName) // Hide field from class { m_derivedtype = null; m_fieldname = fieldName; } } [AttributeUsage(AttributeTargets.Field | AttributeTargets.Class, AllowMultiple = true)] public class InspectorLabel : Attribute { public readonly string m_label; public readonly Type m_derivedtype; public readonly string m_fieldname; public InspectorLabel(string label) // relabel field { m_label = label; m_derivedtype = null; m_fieldname = ""; } public InspectorLabel(string label, Type derivedtype) // relabel field for specific derived type { m_label = label; m_derivedtype = derivedtype; m_fieldname = ""; } public InspectorLabel(string fieldName, string label) // relabel field for class { m_label = label; m_derivedtype = null; m_fieldname = fieldName; } } #if UNITY_EDITOR [UnityEditor.CustomEditor(typeof(MonoBehaviour), true)] [CanEditMultipleObjects()] public class CustomInspectorAttribEditor : UnityEditor.Editor { struct CustomFieldInfo { public bool m_displayField; public string m_label; }; Dictionary m_customField = new Dictionary(); protected virtual void OnEnable() { Type monoType = this.target.GetType(); FieldInfo[] componentFields = monoType.GetFields(BindingFlags.Instance | BindingFlags.Public); FieldInfo[] declaredtFields = monoType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly); CustomFieldInfo custominfo; foreach(FieldInfo field in componentFields) { bool customField = false; custominfo.m_displayField = false; custominfo.m_label = ""; InspectorLabel labelattrib = Attribute.GetCustomAttribute(field, typeof(InspectorLabel)) as InspectorLabel; if ((labelattrib != null) && ((labelattrib.m_derivedtype == null) || labelattrib.m_derivedtype.IsAssignableFrom(monoType))) { custominfo.m_label = labelattrib.m_label; custominfo.m_displayField = true; customField = true; } HideInspectorDerived hidederived = Attribute.GetCustomAttribute(field, typeof(HideInspectorDerived)) as HideInspectorDerived; if(hidederived != null) { if((hidederived.m_derivedtype != null) && hidederived.m_derivedtype.IsAssignableFrom(monoType)) { custominfo.m_displayField = false; customField = true; } else if((hidederived.m_derivedtype == null) && (!declaredtFields.Contains(field))) { custominfo.m_displayField = false; customField = true; } } if(customField && !m_customField.ContainsKey(field.Name)) m_customField.Add (field.Name, custominfo); } HideInspectorDerived [] hidelist = monoType.GetCustomAttributes(typeof(HideInspectorDerived), false) as HideInspectorDerived[]; if((hidelist != null) && (hidelist.Length > 0)) { custominfo.m_displayField = false; custominfo.m_label = ""; foreach(HideInspectorDerived hide in hidelist) { if(hide.m_fieldname != "") { if(m_customField.ContainsKey(hide.m_fieldname)) { m_customField[hide.m_fieldname] = custominfo; // overwrite existing info... } else { m_customField.Add (hide.m_fieldname, custominfo); } } } } InspectorLabel [] labellist = monoType.GetCustomAttributes(typeof(InspectorLabel), false) as InspectorLabel[]; if((labellist != null) && (labellist.Length > 0)) { custominfo.m_displayField = true; custominfo.m_label = ""; foreach(InspectorLabel label in labellist) { if((label.m_fieldname != "") && (label.m_label != "")) { custominfo.m_label = label.m_label; if(m_customField.ContainsKey(label.m_fieldname)) { m_customField[label.m_fieldname] = custominfo; // overwrite existing info... } else { m_customField.Add (label.m_fieldname, custominfo); } } } } } //////////////////////////////// public override void OnInspectorGUI() { DrawDefaultInspector(); } //////////////////////////////// public new bool DrawDefaultInspector() { this.serializedObject.Update(); if (this.serializedObject == null) throw new System.ArgumentNullException("serializedObject"); MonoBehaviour mono = serializedObject.targetObject as MonoBehaviour; Type monoType = mono.GetType(); EditorGUI.BeginChangeCheck(); SerializedProperty iter = serializedObject.GetIterator(); GUIContent label = new GUIContent(); CustomFieldInfo info; bool enterChildren = true; while(iter.NextVisible(enterChildren)) { if(m_customField != null && m_customField.TryGetValue(iter.name, out info)) { if(info.m_displayField) { if(info.m_label != "") { label.text = info.m_label; EditorGUILayout.PropertyField(iter, label, true); } else { EditorGUILayout.PropertyField(iter, true); } } } else { EditorGUILayout.PropertyField(iter, true); } enterChildren = false; } bool result = EditorGUI.EndChangeCheck(); this.serializedObject.ApplyModifiedProperties(); return result; } } #endif }