Newer
Older
Hierarchical-Task-Network-Unity-3D / Assets / Editor / ProceduralGrassEditor.cs
using Codice.Client.BaseCommands;
using Unity.VisualScripting;
using UnityEditor;
using UnityEngine;

[CustomEditor(typeof(ProceduralGrass))]
public class ProceduralGrassEditor : Editor
{
    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();

        GUIStyle headerLabel = new GUIStyle(EditorStyles.label)
        {
            padding = new RectOffset(0, 5, 10, 15),
            margin = new RectOffset(0, 0, 10, 15),
            fontStyle = FontStyle.Bold,
            normal = new GUIStyleState() { textColor = EditorGUIUtility.isProSkin ? Color.gray : new Color(0.4f, 0.4f, 0.4f) }
        };

        GUIStyle valueLabelStyle = new GUIStyle(EditorStyles.miniLabel)
        {
            alignment = TextAnchor.MiddleLeft,
            padding = new RectOffset(2, 2, 0, 0)
        };

        GUIStyle valueLabelStyle_1 = new GUIStyle(EditorStyles.miniLabel)
        {
            alignment = TextAnchor.MiddleRight,
            padding = new RectOffset(-2, -2, 0, 0)
        };

        EditorGUILayout.Space();
        EditorGUILayout.LabelField("Grass Sliders", headerLabel);
        EditorGUILayout.Space(5);

        ProceduralGrass proGrass = (ProceduralGrass)target;

        // Grass Height Slider
        EditorGUILayout.BeginVertical();
        {
            float min, max;
            EditorGUILayout.BeginHorizontal();
            {
                // Label on left
                EditorGUILayout.LabelField("Grass Height", EditorStyles.boldLabel, GUILayout.Width(EditorGUIUtility.labelWidth - 4));

                // Slider taking remaining space
                Vector2 heightRange = proGrass.GrassHeightRange;
                min = heightRange.x;
                max = heightRange.y;

                EditorGUILayout.MinMaxSlider(ref min, ref max, 0, 8f);

                min = TruncateToTwoDecimals(min);
                max = TruncateToTwoDecimals(max);
                proGrass.GrassHeightRange = new Vector2(min, max);
            }
            EditorGUILayout.EndHorizontal();

            // Values centered under slider
            EditorGUILayout.BeginHorizontal();
            {
                GUILayout.Space(EditorGUIUtility.labelWidth);
                EditorGUILayout.LabelField($"Min: {min:F2}", valueLabelStyle, GUILayout.Width(80));
                GUILayout.FlexibleSpace();
                EditorGUILayout.LabelField($"Max: {max:F2}", valueLabelStyle_1, GUILayout.Width(80));
            }
            EditorGUILayout.EndHorizontal();
        }
        EditorGUILayout.EndVertical();

        EditorGUILayout.Space(10);

        // Grass Rotation Slider
        EditorGUILayout.BeginVertical();
        {
            float minRot, maxRot;
            EditorGUILayout.BeginHorizontal();
            {
                EditorGUILayout.LabelField("Grass Rotation", EditorStyles.boldLabel, GUILayout.Width(EditorGUIUtility.labelWidth - 4));

                Vector2 yRotRange = proGrass.GrassYRotationRange;
                minRot = yRotRange.x;
                maxRot = yRotRange.y;

                EditorGUILayout.MinMaxSlider(ref minRot, ref maxRot, 0, 360);

                minRot = Mathf.Round(minRot);
                maxRot = Mathf.Round(maxRot);
                proGrass.GrassYRotationRange = new Vector2(minRot, maxRot);
            }
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            {
                GUILayout.Space(EditorGUIUtility.labelWidth);
                EditorGUILayout.LabelField($"Min: {minRot}°", valueLabelStyle, GUILayout.Width(80));
                GUILayout.FlexibleSpace();
                EditorGUILayout.LabelField($"Max: {maxRot}°", valueLabelStyle_1, GUILayout.Width(80));
            }
            EditorGUILayout.EndHorizontal();
        }
        EditorGUILayout.EndVertical();

        if (GUI.changed)
        {
            EditorUtility.SetDirty(proGrass);
        }
    }

    float TruncateToTwoDecimals(float value) => (float)System.Math.Truncate(value * 100) / 100;
}