static InspectorTypeDrawingConfigDrawer() { //var watch = System.Diagnostics.Stopwatch.StartNew(); using (ProfileSection.Start("InspectorTypeDrawingConfigDrawer static constructor")) { NeverDrawTypes = new HashSet <Type>(FastTypeComparer.Instance); { var networkView = AssemblyUtilities.GetTypeByCachedFullName("UnityEngine.NetworkView"); if (networkView != null) { NeverDrawTypes.Add(networkView); } var gUIText = AssemblyUtilities.GetTypeByCachedFullName("UnityEngine.GUIText"); if (gUIText != null) { NeverDrawTypes.Add(gUIText); } } Type[] unityObjectTypes; using (ProfileSection.Start("Finding all UnityObject types")) { unityObjectTypes = AssemblyUtilities.GetTypes(AssemblyTypeFlags.All) .Where(type => !type.Assembly.IsDynamic() && typeof(UnityEngine.Object).IsAssignableFrom(type) && //TypeExtensions.IsValidIdentifier(type.FullName) && !type.IsDefined <CompilerGeneratedAttribute>() && !type.IsDefined <ObsoleteAttribute>() && !typeof(Joint).IsAssignableFrom(type) && !NeverDrawTypes.Contains(type)) .ToArray(); } Dictionary <Type, Type> haveDrawersAlready = new Dictionary <Type, Type>(FastTypeComparer.Instance); Dictionary <Type, Type> derivedClassDrawnTypes = new Dictionary <Type, Type>(FastTypeComparer.Instance); using (ProfileSection.Start("Search for editors")) { foreach (var type in unityObjectTypes) { if (typeof(Editor).IsAssignableFrom(type)) { try { bool editorForChildClasses; var drawnType = InspectorTypeDrawingConfig.GetEditorDrawnType(type, out editorForChildClasses); if (drawnType != null) { if (!haveDrawersAlready.ContainsKey(drawnType)) { haveDrawersAlready.Add(drawnType, type); } if (editorForChildClasses && !derivedClassDrawnTypes.ContainsKey(drawnType)) { derivedClassDrawnTypes.Add(drawnType, type); } } if (/*type.IsVisible && */ InspectorTypeDrawingConfig.UnityInspectorEditorIsValidBase(type, null)) { PossibleEditorTypes.Add(type); } } catch (TypeLoadException) { } catch (ReflectionTypeLoadException) { } } } ; } using (ProfileSection.Start("Assign editors to Unity objects")) { HashSet <Type> stopBaseTypeLookUpTypes = new HashSet <Type>(FastTypeComparer.Instance) { typeof(object), typeof(Component), typeof(Behaviour), typeof(MonoBehaviour), typeof(UnityEngine.Object), typeof(ScriptableObject), typeof(StateMachineBehaviour), //typeof(Networking.NetworkBehaviour) }; if (UnityNetworkingUtility.NetworkBehaviourType != null) { // UnityEngine.Networking has been removed in Unity 2019+. stopBaseTypeLookUpTypes.Add(UnityNetworkingUtility.NetworkBehaviourType); } //Debug.Log("Searching the following " + unityObjectTypes.Length + " types for Odin-drawable types:\n\n" + string.Join("\n", unityObjectTypes.Select(n => n.GetNiceFullName()).ToArray())); unityObjectTypes.Where(type => /*type.IsVisible && */ !type.IsAbstract && !type.IsGenericTypeDefinition && !type.IsGenericType && !typeof(Editor).IsAssignableFrom(type) && !typeof(EditorWindow).IsAssignableFrom(type)) .ForEach(type => { Type preExistingEditorType; bool haveDrawerAlready = haveDrawersAlready.TryGetValue(type, out preExistingEditorType); if (!haveDrawerAlready) { Type baseType = type.BaseType; while (baseType != null && !stopBaseTypeLookUpTypes.Contains(baseType)) { Type editor; if (derivedClassDrawnTypes.TryGetValue(baseType, out editor)) { haveDrawerAlready = true; preExistingEditorType = editor; break; } baseType = baseType.BaseType; } } if (!haveDrawerAlready) { PossibleDrawnTypes.Add(type); } AddTypeToGroups(type, preExistingEditorType); }); } //Debug.Log("Found the following " + PossibleDrawnTypes.Count + " types that Odin can draw:\n\n" + string.Join("\n", PossibleDrawnTypes.Select(n => n.GetNiceFullName()).ToArray())); // Remove editor entries for any types that are not eligible to be drawn using (ProfileSection.Start("Remove non-eligible editor entries")) { bool fixedAny = false; foreach (var type in InspectorConfig.Instance.DrawingConfig.GetAllDrawnTypesWithEntries()) { if (!PossibleDrawnTypes.Contains(type)) { InspectorConfig.Instance.DrawingConfig.ClearEditorEntryForDrawnType(type); fixedAny = true; } } if (fixedAny) { AssetDatabase.SaveAssets(); } } } //watch.Stop(); //Debug.Log("Init took " + watch.Elapsed.TotalMilliseconds + " ms"); }