Files
BABA_YAGA/Assets/Editor/LevelDecorator.cs
2026-03-26 20:27:19 +07:00

189 lines
7.1 KiB
C#

// ===============================================================================
// LevelDecorator - Professional Environment Randomizer (Chaos Maker)
//
// Creator: Scove
// Last Updated: 2024-05-08
// Version: 2.0
//
// Purpose:
// Quickly adds natural variety to your levels by randomizing the rotation
// and scale of selected objects. Perfect for placing foliage, rocks, or debris.
//
// Key Features:
// 1. Persistent Settings: Remembers your min/max values even after closing Unity.
// 2. Uniform Scale: Toggle between independent axes or proportional scaling.
// 3. Smart Rotation: Control specific Y-axis variance and subtle "tilt" separately.
// 4. Undo Integrated: One click to randomize, one click to undo (Ctrl+Z).
//
// How to Use:
// 1. Place this script in an 'Editor' folder.
// 2. Open via: Menu -> Tools -> Level Decorator (Chaos Maker).
// 3. Select the objects you want to randomize in the Scene.
// 4. Adjust the sliders and click "Apply" or "Randomize Everything".
// ===============================================================================
using UnityEditor;
using UnityEngine;
namespace Editor
{
public class LevelDecorator : EditorWindow
{
// Settings Variables
private Vector3 minScale = new Vector3(0.9f, 0.9f, 0.9f);
private Vector3 maxScale = new Vector3(1.1f, 1.1f, 1.1f);
private float maxRotationY = 180f;
private float maxTilt = 5f;
private bool uniformScale = true;
[MenuItem("Tools/Level Decorator (Chaos Maker)")]
public static void ShowWindow()
{
GetWindow<LevelDecorator>("Chaos Maker");
}
private void OnEnable()
{
LoadSettings();
}
private void LoadSettings()
{
maxRotationY = EditorPrefs.GetFloat("LD_MaxRotY", 180f);
maxTilt = EditorPrefs.GetFloat("LD_MaxTilt", 5f);
uniformScale = EditorPrefs.GetBool("LD_Uniform", true);
minScale.x = EditorPrefs.GetFloat("LD_MinScaleX", 0.9f);
minScale.y = EditorPrefs.GetFloat("LD_MinScaleY", 0.9f);
minScale.z = EditorPrefs.GetFloat("LD_MinScaleZ", 0.9f);
maxScale.x = EditorPrefs.GetFloat("LD_MaxScaleX", 1.1f);
maxScale.y = EditorPrefs.GetFloat("LD_MaxScaleY", 1.1f);
maxScale.z = EditorPrefs.GetFloat("LD_MaxScaleZ", 1.1f);
}
private void SaveSettings()
{
EditorPrefs.SetFloat("LD_MaxRotY", maxRotationY);
EditorPrefs.SetFloat("LD_MaxTilt", maxTilt);
EditorPrefs.SetBool("LD_Uniform", uniformScale);
EditorPrefs.SetFloat("LD_MinScaleX", minScale.x);
EditorPrefs.SetFloat("LD_MinScaleY", minScale.y);
EditorPrefs.SetFloat("LD_MinScaleZ", minScale.z);
EditorPrefs.SetFloat("LD_MaxScaleX", maxScale.x);
EditorPrefs.SetFloat("LD_MaxScaleY", maxScale.y);
EditorPrefs.SetFloat("LD_MaxScaleZ", maxScale.z);
}
private void OnGUI()
{
GUILayout.Label("CHAOS MAKER - RANDOMIZER", EditorStyles.boldLabel);
EditorGUILayout.Space();
EditorGUI.BeginChangeCheck();
// --- ROTATION SECTION ---
EditorGUILayout.BeginVertical("box");
GUILayout.Label("1. Rotation", EditorStyles.boldLabel);
maxRotationY = EditorGUILayout.Slider("Random Y Axis (0-360)", maxRotationY, 0, 360);
maxTilt = EditorGUILayout.Slider("Random Tilt (X & Z)", maxTilt, 0, 45);
if (GUILayout.Button("Randomize Rotation"))
{
ApplyRotation();
}
EditorGUILayout.EndVertical();
EditorGUILayout.Space();
// --- SCALE SECTION ---
EditorGUILayout.BeginVertical("box");
GUILayout.Label("2. Scale", EditorStyles.boldLabel);
uniformScale = EditorGUILayout.Toggle("Uniform Scale", uniformScale);
if (uniformScale)
{
float minU = minScale.x;
float maxU = maxScale.x;
minU = EditorGUILayout.FloatField("Min Scale", minU);
maxU = EditorGUILayout.FloatField("Max Scale", maxU);
minScale = new Vector3(minU, minU, minU);
maxScale = new Vector3(maxU, maxU, maxU);
}
else
{
minScale = EditorGUILayout.Vector3Field("Min Scale", minScale);
maxScale = EditorGUILayout.Vector3Field("Max Scale", maxScale);
}
if (GUILayout.Button("Randomize Scale"))
{
ApplyScale();
}
EditorGUILayout.EndVertical();
EditorGUILayout.Space(10);
// --- MASTER ACTION ---
GUI.backgroundColor = new Color(0.7f, 1f, 0.7f); // Light green button
if (GUILayout.Button("RANDOMIZE EVERYTHING", GUILayout.Height(40)))
{
ApplyRotation();
ApplyScale();
}
GUI.backgroundColor = Color.white;
if (EditorGUI.EndChangeCheck())
{
SaveSettings();
}
EditorGUILayout.Space();
int selectCount = Selection.transforms.Length;
EditorGUILayout.HelpBox($"Objects Selected: {selectCount}\nSettings are automatically saved.", MessageType.None);
}
private void ApplyRotation()
{
if (Selection.transforms.Length == 0) return;
Undo.RecordObjects(Selection.transforms, "Chaos Rotation");
foreach (Transform t in Selection.transforms)
{
Vector3 currentRot = t.localEulerAngles;
float randY = Random.Range(-maxRotationY, maxRotationY);
float randX = Random.Range(-maxTilt, maxTilt);
float randZ = Random.Range(-maxTilt, maxTilt);
t.localEulerAngles = new Vector3(currentRot.x + randX, currentRot.y + randY, currentRot.z + randZ);
}
Debug.Log($"<color=#FF8800><b>[LevelDecorator]</b></color> Rotation randomized for {Selection.transforms.Length} objects.");
}
private void ApplyScale()
{
if (Selection.transforms.Length == 0) return;
Undo.RecordObjects(Selection.transforms, "Chaos Scale");
foreach (Transform t in Selection.transforms)
{
if (uniformScale)
{
float uniformRnd = Random.Range(minScale.x, maxScale.x);
t.localScale = new Vector3(uniformRnd, uniformRnd, uniformRnd);
}
else
{
float rX = Random.Range(minScale.x, maxScale.x);
float rY = Random.Range(minScale.y, maxScale.y);
float rZ = Random.Range(minScale.z, maxScale.z);
t.localScale = new Vector3(rX, rY, rZ);
}
}
Debug.Log($"<color=#FF8800><b>[LevelDecorator]</b></color> Scale randomized for {Selection.transforms.Length} objects.");
}
}
}