static void PreferencesGUI() { EditorGUILayout.BeginVertical(); EditorGUILayout.Space(); #if HAS_MINIMUM_REQUIRED_VERSION // Max execution time { var label = new GUIContent("Max Execution Time (ms)", "One of the features of AutoLOD is to keep the editor running responsively, so it’s possible to set" + "the max execution time for coroutines that run. AutLOD will spawn LOD generators on separate " + "threads, however, some generators may require main thread usage for accessing non thread-safe " + "Unity data structures and classes."); if (maxExecutionTime == 0) { EditorGUILayout.BeginHorizontal(); if (!EditorGUILayout.Toggle(label, true)) { maxExecutionTime = 1; } GUILayout.Label("Infinity"); GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); } else { EditorGUI.BeginChangeCheck(); var maxTime = EditorGUILayout.IntSlider(label, maxExecutionTime, 0, 15); if (EditorGUI.EndChangeCheck()) { maxExecutionTime = maxTime; } } } // Mesh simplifier { var type = meshSimplifierType; if (type != null) { var label = new GUIContent("Default Mesh Simplifier", "All simplifiers (IMeshSimplifier) are " + "enumerated and provided here for selection. By allowing for multiple implementations, " + "different approaches can be compared. The default mesh simplifier is used to generate LODs " + "on import and when explicitly called."); var displayedOptions = meshSimplifiers.Select(t => t.Name).ToArray(); EditorGUI.BeginChangeCheck(); var selected = EditorGUILayout.Popup(label, Array.IndexOf(displayedOptions, type.Name), displayedOptions); if (EditorGUI.EndChangeCheck()) { meshSimplifierType = meshSimplifiers[selected]; } if (meshSimplifierType != null && typeof(IMeshSimplifier).IsAssignableFrom(meshSimplifierType)) { if (s_SimplifierPreferences == null || s_SimplifierPreferences.GetType() != meshSimplifierType) { s_SimplifierPreferences = (IPreferences)Activator.CreateInstance(meshSimplifierType); } if (s_SimplifierPreferences != null) { EditorGUI.indentLevel++; s_SimplifierPreferences.OnPreferencesGUI(); EditorGUI.indentLevel--; } } } else { EditorGUILayout.HelpBox("No IMeshSimplifiers found!", MessageType.Warning); } } // Batcher { var type = batcherType; if (type != null) { var label = new GUIContent("Default Batcher", "All simplifiers (IMeshSimplifier) are " + "enumerated and provided here for selection. By allowing for multiple implementations, " + "different approaches can be compared. The default batcher is used in HLOD generation when " + "combining objects that are located within the same LODVolume."); var displayedOptions = batchers.Select(t => t.Name).ToArray(); EditorGUI.BeginChangeCheck(); var selected = EditorGUILayout.Popup(label, Array.IndexOf(displayedOptions, type.Name), displayedOptions); if (EditorGUI.EndChangeCheck()) { batcherType = batchers[selected]; } } else { EditorGUILayout.HelpBox("No IBatchers found!", MessageType.Warning); } } // Max LOD { var label = new GUIContent("Maximum LOD Generated", "Controls the depth of the generated LOD chain"); var maxLODValues = Enumerable.Range(0, LODData.MaxLOD + 1).ToArray(); EditorGUI.BeginChangeCheck(); int maxLODGenerated = EditorGUILayout.IntPopup(label, maxLOD, maxLODValues.Select(v => new GUIContent(v.ToString())).ToArray(), maxLODValues); if (EditorGUI.EndChangeCheck()) { maxLOD = maxLODGenerated; } } // Control LOD0 maximum poly count { var label = new GUIContent("Initial LOD Max Poly Count", "In the case where non realtime-ready assets " + "are brought into Unity these would normally perform poorly. Being able to set a max poly count " + "for LOD0 allows even the largest of meshes to import with performance-minded defaults."); EditorGUI.BeginChangeCheck(); var maxPolyCount = EditorGUILayout.IntField(label, initialLODMaxPolyCount); if (EditorGUI.EndChangeCheck()) { initialLODMaxPolyCount = maxPolyCount; } } // Generate LODs on import { var label = new GUIContent("Generate on Import", "Controls whether automatic LOD generation will happen " + "on import. Even if this option is disabled it is still possible to generate LOD chains " + "individually on individual files."); EditorGUI.BeginChangeCheck(); var generateLODsOnImport = EditorGUILayout.Toggle(label, generateOnImport); if (EditorGUI.EndChangeCheck()) { generateOnImport = generateLODsOnImport; } } // Turn off/on saving assets (performance feature { var label = new GUIContent("Save Assets", "This can speed up performance, but may cause errors with some simplifiers"); EditorGUI.BeginChangeCheck(); var saveAssetsOnImport = EditorGUILayout.Toggle(label, saveAssets); if (EditorGUI.EndChangeCheck()) { saveAssets = saveAssetsOnImport; } } // Use SceneLOD? { var label = new GUIContent("Scene LOD", "Enable Hierarchical LOD (HLOD) support for scenes, " + "which will automatically generate and stay updated in the background."); EditorGUI.BeginChangeCheck(); var enabled = EditorGUILayout.Toggle(label, sceneLODEnabled); if (EditorGUI.EndChangeCheck()) { sceneLODEnabled = enabled; } if (sceneLODEnabled) { label = new GUIContent("Show Volume Bounds", "This will display the bounds visually of the bounding " + "volume hierarchy (currently an Octree)"); EditorGUI.indentLevel++; EditorGUI.BeginChangeCheck(); var showBounds = EditorGUILayout.Toggle(label, showVolumeBounds); if (EditorGUI.EndChangeCheck()) { showVolumeBounds = showBounds; } var sceneLOD = SceneLOD.instance; EditorGUILayout.HelpBox(string.Format("Coroutine Queue: {0}\nCurrent Execution Time: {1:0.00} s", sceneLOD.coroutineQueueRemaining, sceneLOD.coroutineCurrentExecutionTime * 0.001f), MessageType.None); // Force more frequent updating var mouseOverWindow = EditorWindow.mouseOverWindow; if (mouseOverWindow) { mouseOverWindow.Repaint(); } EditorGUI.indentLevel--; } } #else EditorGUILayout.HelpBox(k_MinimumRequiredVersion, MessageType.Warning); #endif EditorGUILayout.EndVertical(); }