189 lines
7.1 KiB
C#
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.");
|
|
}
|
|
}
|
|
} |