internal static void Rebuild(Assembly assembly) { System.Type[] typesFromAssembly = AssemblyHelper.GetTypesFromAssembly(assembly); foreach (System.Type type in typesFromAssembly) { object[] customAttributes = type.GetCustomAttributes(typeof(CustomEditor), false); foreach (CustomEditor editor in customAttributes) { MonoEditorType item = new MonoEditorType(); if (editor.m_InspectedType == null) { Debug.Log("Can't load custom inspector " + type.Name + " because the inspected type is null."); } else if (!type.IsSubclassOf(typeof(Editor))) { if (((type.FullName != "TweakMode") || !type.IsEnum) || (editor.m_InspectedType.FullName != "BloomAndFlares")) { Debug.LogWarning(type.Name + " uses the CustomEditor attribute but does not inherit from Editor.\nYou must inherit from Editor. See the Editor class script documentation."); } } else { item.m_InspectedType = editor.m_InspectedType; item.m_InspectorType = type; item.m_EditorForChildClasses = editor.m_EditorForChildClasses; item.m_IsFallback = editor.isFallback; kSCustomEditors.Add(item); if (type.GetCustomAttributes(typeof(CanEditMultipleObjects), false).Length > 0) { kSCustomMultiEditors.Add(item); } } } } }
private static int SortUnityTypesFirst(MonoEditorType typeA, MonoEditorType typeB) { if (typeA == null && typeB == null) { return(0); } else if (typeA == null) { return(-1); } else if (typeB == null) { return(1); } var xAssemblyName = typeA.m_InspectorType.Assembly.GetName().ToString(); var yAssemblyName = typeB.m_InspectorType.Assembly.GetName().ToString(); var xAssemblyIsUnity = xAssemblyName.StartsWith("Unity.") || xAssemblyName.StartsWith("UnityEditor.") || xAssemblyName.StartsWith("UnityEngine."); var yAssemblyIsUnity = yAssemblyName.StartsWith("Unity.") || yAssemblyName.StartsWith("UnityEditor.") || yAssemblyName.StartsWith("UnityEngine."); if ((xAssemblyIsUnity && yAssemblyIsUnity) || (!xAssemblyIsUnity && !yAssemblyIsUnity)) { return(0); } else if (xAssemblyIsUnity && !yAssemblyIsUnity) { return(1); } else if (!xAssemblyIsUnity && yAssemblyIsUnity) { return(-1); } return(xAssemblyName.CompareTo(yAssemblyName)); }
internal static void Rebuild(Assembly assembly) { Type[] typesFromAssembly = AssemblyHelper.GetTypesFromAssembly(assembly); foreach (Type type in typesFromAssembly) { object[] customAttributes = type.GetCustomAttributes(typeof(CustomEditor), false); foreach (CustomEditor editor in customAttributes) { MonoEditorType item = new MonoEditorType(); if (editor.m_InspectedType == null) { Debug.Log("Can't load custom inspector " + type.Name + " because the inspected type is null."); } else if (!type.IsSubclassOf(typeof(Editor))) { if (((type.FullName != "TweakMode") || !type.IsEnum) || (editor.m_InspectedType.FullName != "BloomAndFlares")) { Debug.LogWarning(type.Name + " uses the CustomEditor attribute but does not inherit from Editor.\nYou must inherit from Editor. See the Editor class script documentation."); } } else { item.m_InspectedType = editor.m_InspectedType; item.m_InspectorType = type; item.m_EditorForChildClasses = editor.m_EditorForChildClasses; item.m_IsFallback = editor.isFallback; kSCustomEditors.Add(item); if (type.GetCustomAttributes(typeof(CanEditMultipleObjects), false).Length > 0) { kSCustomMultiEditors.Add(item); } } } } }
private static bool IsAppropriateEditor(MonoEditorType editor, System.Type parentClass, bool isChildClass, bool isFallback) { if (isChildClass && !editor.m_EditorForChildClasses) { return(false); } if (isFallback != editor.m_IsFallback) { return(false); } return(parentClass == editor.m_InspectedType); }
private static bool IsAppropriateEditor(MonoEditorType editor, Type parentClass, bool isChildClass, bool isFallback) { if (isChildClass && !editor.m_EditorForChildClasses) { return false; } if (isFallback != editor.m_IsFallback) { return false; } return (parentClass == editor.m_InspectedType); }
private static bool IsAppropriateEditor(MonoEditorType editor, Type parentClass, bool isChildClass, bool isFallback) { if (isChildClass && !editor.m_EditorForChildClasses) { // skip if it's a child class and this editor doesn't want to match on children return(false); } if (isFallback != editor.m_IsFallback) { return(false); } return(parentClass == editor.m_InspectedType || (parentClass.IsGenericType && parentClass.GetGenericTypeDefinition() == editor.m_InspectedType)); }
static MadEditorConfig() { CustomEditorAttributesType = typeof(Editor).Assembly.GetType("UnityEditor.CustomEditorAttributes"); CustomEditorAttributesType_Initialized = CustomEditorAttributesType.GetField("s_Initialized", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); CustomEditorAttributesType_CachedEditorForType = CustomEditorAttributesType.GetField("kCachedEditorForType", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); CustomEditorAttributesType_CachedMultiEditorForType = CustomEditorAttributesType.GetField("kCachedMultiEditorForType", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); CustomEditorAttributesType_CustomEditors = CustomEditorAttributesType.GetField("kSCustomEditors", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); CustomEditorAttributesType_CustomMultiEditors = CustomEditorAttributesType.GetField("kSCustomMultiEditors", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); MonoEditorType = CustomEditorAttributesType.GetNestedType("MonoEditorType", BindingFlags.Public | BindingFlags.NonPublic); MonoEditorType_InspectedType = MonoEditorType.GetField("m_InspectedType", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); MonoEditorType_InspectorType = MonoEditorType.GetField("m_InspectorType", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); MonoEditorType_EditorForChildClasses = MonoEditorType.GetField("m_EditorForChildClasses", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); MonoEditorType_IsFallback = MonoEditorType.GetField("m_IsFallback", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); CustomEditorType = typeof(CustomEditor); CustomEditor_InspectedTypeField = typeof(CustomEditor).GetField("m_InspectedType", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); CustomEditor_EditorForChildClassesField = typeof(CustomEditor).GetField("m_EditorForChildClasses", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); BindEditors(); }
// editor: 找到的Editor // parentClass: editor对应的类型 // isChildClass: 找到的是type的基类的editor // isFallback: 是否是第二次pass // * 标记了isFallback的编辑器 // * 只有在,没有找到标记了isFallback的编辑器,之后,才会被选择 private static bool IsAppropriateEditor(MonoEditorType editor, Type parentClass, bool isChildClass, bool isFallback) { // 检查,基类的editor,是否支持编辑子类 if (isChildClass && !editor.m_EditorForChildClasses) { // skip if it's a child class and this editor doesn't want to match on children return(false); } // 第一遍:isFallback = false // 第二遍:isFallback = true if (isFallback != editor.m_IsFallback) { return(false); } // Editor不是通过T找到的 || // 是通过T找到的Editor,并且Editor是T类型的编辑器 // T: 感觉这个判断有点多余,当前调用的情况下,应该总是true return(parentClass == editor.m_InspectedType || (parentClass.IsGenericType && parentClass.GetGenericTypeDefinition() == editor.m_InspectedType)); }
internal static void Rebuild() { kSCustomEditors.Clear(); kSCustomMultiEditors.Clear(); var types = TypeCache.GetTypesWithAttribute <CustomEditor>(); foreach (var type in types) { object[] attrs = type.GetCustomAttributes(typeof(CustomEditor), false); foreach (CustomEditor inspectAttr in attrs) { var t = new MonoEditorType(); if (inspectAttr.m_InspectedType == null) { Debug.Log("Can't load custom inspector " + type.Name + " because the inspected type is null."); } else if (!type.IsSubclassOf(typeof(Editor))) { // Suppress a warning on TweakMode, we did this bad in the default project folder // and it's going to be too hard for customers to figure out how to fix it and also quite pointless. if (type.FullName == "TweakMode" && type.IsEnum && inspectAttr.m_InspectedType.FullName == "BloomAndFlares") { continue; } Debug.LogWarning( type.Name + " uses the CustomEditor attribute but does not inherit from Editor.\nYou must inherit from Editor. See the Editor class script documentation."); } else { t.m_InspectedType = inspectAttr.m_InspectedType; t.m_InspectorType = type; t.m_EditorForChildClasses = inspectAttr.m_EditorForChildClasses; t.m_IsFallback = inspectAttr.isFallback; var attr = inspectAttr as CustomEditorForRenderPipelineAttribute; if (attr != null) { t.m_RenderPipelineType = attr.renderPipelineType; } List <MonoEditorType> editors; if (!kSCustomEditors.TryGetValue(inspectAttr.m_InspectedType, out editors)) { editors = new List <MonoEditorType>(); kSCustomEditors[inspectAttr.m_InspectedType] = editors; } editors.Add(t); if (type.GetCustomAttributes(typeof(CanEditMultipleObjects), false).Length > 0) { List <MonoEditorType> multiEditors; if (!kSCustomMultiEditors.TryGetValue(inspectAttr.m_InspectedType, out multiEditors)) { multiEditors = new List <MonoEditorType>(); kSCustomMultiEditors[inspectAttr.m_InspectedType] = multiEditors; } multiEditors.Add(t); } } } } }
// 用来搜索Assembly中的, // 所有类的[CustomEditor]和[CanEditMultipleObjects]标签,标记情况 internal static void Rebuild(Assembly assembly) { // 获取Assembly中全部类型 Type[] types = AssemblyHelper.GetTypesFromAssembly(assembly); foreach (var type in types) { // 获取CustomEditor标签 // false参数:不搜索父亲链 object[] attrs = type.GetCustomAttributes(typeof(CustomEditor), false); // Q: 一个类可以有多个CustomEditor? // 是可以有的,应该是多个inspectedType,可以拥有相同的界面代码 foreach (CustomEditor inspectAttr in attrs) { // CustomEditor的数据存储 var t = new MonoEditorType(); // 检查CustomEditor标签参数 if (inspectAttr.m_InspectedType == null) { Debug.Log("Can't load custom inspector " + type.Name + " because the inspected type is null."); } // 检查CustomEditor挂载的类,是Editor else if (!type.IsSubclassOf(typeof(Editor))) { // Q: 特殊处理TweakMode? // Suppress a warning on TweakMode, we did this bad in the default project folder // and it's going to be too hard for customers to figure out how to fix it and also quite pointless. if (type.FullName == "TweakMode" && type.IsEnum && inspectAttr.m_InspectedType.FullName == "BloomAndFlares") { continue; } Debug.LogWarning( type.Name + " uses the CustomEditor attribute but does not inherit from Editor.\nYou must inherit from Editor. See the Editor class script documentation."); } else { // 将CustomEditor标记的参数, // 存储到MonoEditorType结构中 t.m_InspectedType = inspectAttr.m_InspectedType; t.m_InspectorType = type; t.m_EditorForChildClasses = inspectAttr.m_EditorForChildClasses; // Q: CustomEditor.isFallback的含义? t.m_IsFallback = inspectAttr.isFallback; // 特殊存储CustomEditorForRenderPipelineAttribute的参数 // Q: CustomEditorForRenderPipelineAttribute,根据RenderPipeline来改变显示的标签 var attr = inspectAttr as CustomEditorForRenderPipelineAttribute; if (attr != null) { t.m_RenderPipelineType = attr.renderPipelineType; } List <MonoEditorType> editors; // 确保dic中,有inspectedType的 List<MonoEditorType> if (!kSCustomEditors.TryGetValue(inspectAttr.m_InspectedType, out editors)) { editors = new List <MonoEditorType>(); kSCustomEditors[inspectAttr.m_InspectedType] = editors; } // 将新的CustomEditor标签数据 // 加入到列表中 editors.Add(t); // 检查是否有, [CanEditMultipleObjects]标签 if (type.GetCustomAttributes(typeof(CanEditMultipleObjects), false).Length > 0) { List <MonoEditorType> multiEditors; // 确保有 List<MonoEditorType> if (!kSCustomMultiEditors.TryGetValue(inspectAttr.m_InspectedType, out multiEditors)) { multiEditors = new List <MonoEditorType>(); kSCustomMultiEditors[inspectAttr.m_InspectedType] = multiEditors; } // 加入到列表 multiEditors.Add(t); } } } } }