public static int ShowTerrainLayersSelectionHelper(Terrain terrain, int activeTerrainLayer) { GUILayout.Label(s_Styles.terrainLayers, EditorStyles.boldLabel); GUI.changed = false; int selectedTerrainLayer = activeTerrainLayer; if (terrain.terrainData.terrainLayers.Length > 0) { TerrainLayer[] layers = terrain.terrainData.terrainLayers; var layerGUIContents = new GUIContent[layers.Length]; for (int i = 0; i < layers.Length; ++i) { layerGUIContents[i] = new GUIContent { image = (layers[i] == null || layers[i].diffuseTexture == null) ? EditorGUIUtility.whiteTexture : AssetPreview.GetAssetPreview(layers[i].diffuseTexture) ?? layers[i].diffuseTexture, text = layers[i] == null ? "Missing" : layers[i].name, tooltip = layers[i] == null ? "Missing" : layers[i].name }; } selectedTerrainLayer = TerrainInspector.AspectSelectionGridImageAndText(activeTerrainLayer, layerGUIContents, 64, s_Styles.errNoLayersFound, out _); } else { selectedTerrainLayer = -1; } GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); // menu button Rect r = GUILayoutUtility.GetRect(s_Styles.btnEditTerrainLayers, new GUIStyle("Button")); if (GUI.Button(r, s_Styles.btnEditTerrainLayers, new GUIStyle("Button"))) { MenuCommand context = new MenuCommand(terrain, selectedTerrainLayer); EditorUtility.DisplayPopupMenu(new Rect(r.x, r.y, 0, 0), "CONTEXT /TerrainLayers", context); } GUILayout.EndHorizontal(); return(selectedTerrainLayer); }
public override void OnInspectorGUI(Terrain terrain, IOnInspectorGUI editContext) { if (s_Styles == null) { s_Styles = new Styles(); } DetailPrototype[] prototypes = terrain.terrainData.detailPrototypes; var detailIcons = LoadDetailIcons(prototypes); // Detail picker GUILayout.Label(s_Styles.details, EditorStyles.boldLabel); selectedDetail = TerrainInspector.AspectSelectionGridImageAndText(selectedDetail, prototypes.Length, (i, rect, style, controlID) => { bool renderModeSupported = DetailPrototype.IsModeSupportedByRenderPipeline(prototypes[i].renderMode, prototypes[i].useInstancing, out var errorMessage); bool mouseHover = rect.Contains(Event.current.mousePosition); if (Event.current.type == EventType.Repaint) { bool wasEnabled = GUI.enabled; GUI.enabled &= renderModeSupported; style.Draw(rect, detailIcons[i], GUI.enabled && mouseHover && (GUIUtility.hotControl == 0 || GUIUtility.hotControl == controlID), GUI.enabled && GUIUtility.hotControl == controlID, i == selectedDetail, false); GUI.enabled = wasEnabled; } if (!renderModeSupported) { var tmpContent = EditorGUIUtility.TempContent(EditorGUIUtility.GetHelpIcon(MessageType.Error)); tmpContent.tooltip = errorMessage; GUI.Label(new Rect(rect.xMax - 16, rect.yMin + 1, 19, 19), tmpContent); } if (mouseHover) { GUIUtility.mouseUsed = true; GUIStyle.SetMouseTooltip(detailIcons[i].tooltip, rect); } }, 64, s_Styles.noDetailObjectDefined, out var doubleClick); if (doubleClick) { TerrainDetailContextMenus.EditDetail(new MenuCommand(terrain, selectedDetail)); GUIUtility.ExitGUI(); } if (selectedDetail >= 0 && selectedDetail < prototypes.Length) { ShowDetailPrototypeMessages(prototypes[selectedDetail], terrain); } var terrainInspector = TerrainInspector.s_activeTerrainInspectorInstance; GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); TerrainInspector.MenuButton(s_Styles.editDetails, "CONTEXT/TerrainEngineDetails", terrain, selectedDetail); terrainInspector.ShowRefreshPrototypes(); GUILayout.EndHorizontal(); terrainInspector.ShowDetailStats(); EditorGUILayout.Space(); // Brush selector editContext.ShowBrushesGUI(0, BrushGUIEditFlags.Select, 0); // Brush size terrainInspector.brushSize = EditorGUILayout.PowerSlider(s_Styles.brushSize, Mathf.Clamp(terrainInspector.brushSize, 1, 100), 1, 100, 4); detailOpacity = EditorGUILayout.Slider(s_Styles.opacity, detailOpacity, 0, 1); // Strength detailStrength = EditorGUILayout.Slider(s_Styles.detailTargetStrength, detailStrength, 0, 1); // Brush editor editContext.ShowBrushesGUI((int)EditorGUIUtility.singleLineHeight, BrushGUIEditFlags.Inspect); }
public override void OnInspectorGUI(Terrain terrain, IOnInspectorGUI editContext) { LoadTreeIcons(terrain); // Tree picker GUI.changed = false; ShowUpgradeTreePrototypeScaleUI(terrain); GUILayout.Label(Styles.trees, EditorStyles.boldLabel); selectedTree = TerrainInspector.AspectSelectionGridImageAndText(selectedTree, m_TreeContents, 64, Styles.noTreesDefined, out var doubleClick); if (selectedTree >= m_TreeContents.Length) { selectedTree = PaintTreesTool.kInvalidTree; } if (doubleClick) { TerrainTreeContextMenus.EditTree(new MenuCommand(terrain, selectedTree)); GUIUtility.ExitGUI(); } GUILayout.BeginHorizontal(); using (new EditorGUI.DisabledScope(selectedTree == PaintTreesTool.kInvalidTree)) { if (GUILayout.Button(Styles.massPlaceTrees)) { TerrainMenus.MassPlaceTrees(); } } GUILayout.FlexibleSpace(); TerrainInspector.MenuButton(Styles.editTrees, "CONTEXT/TerrainEngineTrees", terrain, selectedTree); TerrainInspector.ShowRefreshPrototypes(); GUILayout.EndHorizontal(); GUILayout.Label(TerrainInspector.styles.settings, EditorStyles.boldLabel); // Placement distance brushSize = TerrainInspectorUtility.PowerSlider(TerrainInspector.styles.brushSize, brushSize, 1, Mathf.Min(terrain.terrainData.size.x, terrain.terrainData.size.z), 4.0f); float oldDens = (3.3f - spacing) / 3f; float newDens = TerrainInspectorUtility.ScaledSliderWithRounding(Styles.treeDensity, oldDens, 0.1f, 1.0f, 100.0f, 1.0f); // Only set spacing when value actually changes. Otherwise // it will lose precision because we're constantly doing math // back and forth with it. if (newDens != oldDens) { spacing = (1.1f - newDens) * 3f; } GUILayout.Space(5); GUILayout.BeginHorizontal(); GUILayout.Label(Styles.treeHeight, GUILayout.Width(EditorGUIUtility.labelWidth - 6)); GUILayout.Label(Styles.treeHeightRandomLabel, GUILayout.ExpandWidth(false)); allowHeightVar = GUILayout.Toggle(allowHeightVar, Styles.treeHeightRandomToggle, GUILayout.ExpandWidth(false)); if (allowHeightVar) { EditorGUI.BeginChangeCheck(); float min = treeHeight * (1.0f - treeHeightVariation); float max = treeHeight * (1.0f + treeHeightVariation); EditorGUILayout.MinMaxSlider(ref min, ref max, 0.01f, 2.0f); if (EditorGUI.EndChangeCheck()) { treeHeight = (min + max) * 0.5f; treeHeightVariation = (max - min) / (min + max); } } else { treeHeight = EditorGUILayout.Slider(treeHeight, 0.01f, 2.0f); treeHeightVariation = 0.0f; } GUILayout.EndHorizontal(); GUILayout.Space(5); lockWidthToHeight = EditorGUILayout.Toggle(Styles.lockWidthToHeight, lockWidthToHeight); GUILayout.Space(5); using (new EditorGUI.DisabledScope(lockWidthToHeight)) { GUILayout.BeginHorizontal(); GUILayout.Label(Styles.treeWidth, GUILayout.Width(EditorGUIUtility.labelWidth - 6)); GUILayout.Label(Styles.treeWidthRandomLabel, GUILayout.ExpandWidth(false)); allowWidthVar = GUILayout.Toggle(allowWidthVar, Styles.treeWidthRandomToggle, GUILayout.ExpandWidth(false)); if (allowWidthVar) { EditorGUI.BeginChangeCheck(); float min = treeWidth * (1.0f - treeWidthVariation); float max = treeWidth * (1.0f + treeWidthVariation); EditorGUILayout.MinMaxSlider(ref min, ref max, 0.01f, 2.0f); if (EditorGUI.EndChangeCheck()) { treeWidth = (min + max) * 0.5f; treeWidthVariation = (max - min) / (min + max); } } else { treeWidth = EditorGUILayout.Slider(treeWidth, 0.01f, 2.0f); treeWidthVariation = 0.0f; } GUILayout.EndHorizontal(); } if (selectedTree == PaintTreesTool.kInvalidTree) { return; } GUILayout.Space(5); GameObject prefab = terrain.terrainData.treePrototypes[selectedTree].m_Prefab; string treePrototypeWarning; terrain.terrainData.treePrototypes[selectedTree].Validate(out treePrototypeWarning); bool isLodTreePrototype = TerrainEditorUtility.IsLODTreePrototype(prefab); using (new EditorGUI.DisabledScope(!isLodTreePrototype)) { randomRotation = EditorGUILayout.Toggle(Styles.treeRotation, randomRotation); } if (!isLodTreePrototype) { EditorGUILayout.HelpBox(Styles.treeRotationDisabled.text, MessageType.Info); } if (!string.IsNullOrEmpty(treePrototypeWarning)) { EditorGUILayout.HelpBox(treePrototypeWarning, MessageType.Warning); } // TODO: we should check if the shaders assigned to this 'tree' support _TreeInstanceColor or not.. complicated check though treeColorAdjustment = EditorGUILayout.Slider(Styles.treeColorVar, treeColorAdjustment, 0, 1); if (prefab != null) { StaticEditorFlags staticEditorFlags = GameObjectUtility.GetStaticEditorFlags(prefab); bool contributeGI = (staticEditorFlags & StaticEditorFlags.ContributeGI) != 0; using (new EditorGUI.DisabledScope(true)) // Always disabled, because we don't want to edit the prefab. contributeGI = EditorGUILayout.Toggle(Styles.treeContributeGI, contributeGI); } }