Example #1
0
        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);
            }
        }