Files
HauntedBloodlines/Assets/Editor/ChangeLightColourBatchTool.cs
2025-05-29 22:31:40 +03:00

312 lines
12 KiB
C#

using UnityEditor;
using UnityEngine;
using System.Collections.Generic;
using System.Reflection;
public class ChangeLightColourBatchTool : EditorWindow
{
private string newChildObjectName = "LightLogic";
private List<string> lampRendererNames = new List<string> { "Lamp" };
private List<string> lightRendererNames = new List<string> { "Bulb" };
private Material lampRendererMaterial;
private Material lightRendererMaterial;
private Color lightColour = Color.white;
private bool onlyActiveLights = true;
private bool allowSharedRenderers = false;
private List<int> lampMaterialIndices = new List<int> { 0 };
private List<int> lightMaterialIndices = new List<int> { 0 };
private LightSetupPreset loadedPreset;
[MenuItem("Tools/Light Tools/Auto Setup Light Logic")]
public static void ShowWindow()
{
GetWindow<ChangeLightColourBatchTool>("Auto Setup Light Logic");
}
private void OnGUI()
{
GUILayout.Label("Setup Light Logic on Selected Objects", EditorStyles.boldLabel);
newChildObjectName = EditorGUILayout.TextField("New Child Name", newChildObjectName);
GUILayout.Space(10);
DrawStringList("Lamp Renderer Name(s)", lampRendererNames);
DrawStringList("Light Renderer Name(s)", lightRendererNames);
GUILayout.Space(10);
lampRendererMaterial = (Material)EditorGUILayout.ObjectField("Lamp Renderer Material", lampRendererMaterial, typeof(Material), false);
lightRendererMaterial = (Material)EditorGUILayout.ObjectField("Light Renderer Material", lightRendererMaterial, typeof(Material), false);
GUILayout.Space(10);
DrawIntList("Lamp Material Indices", lampMaterialIndices);
DrawIntList("Light Material Indices", lightMaterialIndices);
GUILayout.Space(10);
lightColour = EditorGUILayout.ColorField("Light Colour", lightColour);
onlyActiveLights = EditorGUILayout.Toggle("Only Active Lights", onlyActiveLights);
allowSharedRenderers = EditorGUILayout.Toggle("Allow Shared Renderers", allowSharedRenderers);
GUILayout.Space(10);
if (GUILayout.Button("Apply to Selected Objects"))
{
foreach (GameObject selected in Selection.gameObjects)
{
CreateLightLogicObject(selected);
}
}
GUILayout.Space(10);
if (GUILayout.Button("Update Fields on Existing ChangeLightColour"))
{
foreach (GameObject selected in Selection.gameObjects)
{
ReplaceFieldsOnExistingLightLogic(selected);
}
}
GUILayout.Space(15);
GUILayout.Label("Preset Management", EditorStyles.boldLabel);
loadedPreset = (LightSetupPreset)EditorGUILayout.ObjectField("Loaded Preset", loadedPreset, typeof(LightSetupPreset), false);
if (GUILayout.Button("Overwrite Loaded Preset"))
{
if (loadedPreset != null)
{
bool confirm = EditorUtility.DisplayDialog(
"Overwrite Preset",
$"Are you sure you want to overwrite the loaded preset '{loadedPreset.name}' with current settings?",
"Yes, Overwrite",
"Cancel"
);
if (confirm)
{
SaveCurrentToPreset(loadedPreset);
EditorUtility.SetDirty(loadedPreset);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
Debug.Log($"✅ Overwritten preset: {AssetDatabase.GetAssetPath(loadedPreset)}");
}
}
else
{
Debug.LogWarning("No preset loaded to overwrite.");
}
}
if (GUILayout.Button("Save Current As New Preset"))
{
string path = EditorUtility.SaveFilePanelInProject("Save Preset", "NewLightSetupPreset", "asset", "Save Light Setup Preset", "Assets/Presets");
if (!string.IsNullOrEmpty(path))
{
var newPreset = ScriptableObject.CreateInstance<LightSetupPreset>();
SaveCurrentToPreset(newPreset);
AssetDatabase.CreateAsset(newPreset, path);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
Debug.Log($"✅ Preset saved at: {path}");
}
}
if (GUILayout.Button("Load Preset From File..."))
{
string path = EditorUtility.OpenFilePanel("Select Light Setup Preset", "Assets/Presets", "asset");
if (!string.IsNullOrEmpty(path) && path.StartsWith(Application.dataPath))
{
string relativePath = "Assets" + path.Substring(Application.dataPath.Length);
var preset = AssetDatabase.LoadAssetAtPath<LightSetupPreset>(relativePath);
if (preset != null)
{
loadedPreset = preset;
LoadPreset(loadedPreset);
Debug.Log($"✅ Loaded preset from: {relativePath}");
}
else
{
Debug.LogError("❌ Failed to load preset. Are you sure it's a LightSetupPreset?");
}
}
}
}
private void DrawStringList(string label, List<string> list)
{
GUILayout.Label(label, EditorStyles.boldLabel);
int removeIndex = -1;
for (int i = 0; i < list.Count; i++)
{
EditorGUILayout.BeginHorizontal();
list[i] = EditorGUILayout.TextField($"Name {i + 1}", list[i]);
if (GUILayout.Button("-", GUILayout.Width(20))) removeIndex = i;
EditorGUILayout.EndHorizontal();
}
if (removeIndex >= 0 && list.Count > 1) list.RemoveAt(removeIndex);
if (GUILayout.Button("+ Add")) list.Add("");
}
private void DrawIntList(string label, List<int> list)
{
GUILayout.Label(label, EditorStyles.boldLabel);
int removeIndex = -1;
for (int i = 0; i < list.Count; i++)
{
EditorGUILayout.BeginHorizontal();
list[i] = EditorGUILayout.IntField($"Index {i + 1}", list[i]);
if (GUILayout.Button("-", GUILayout.Width(20))) removeIndex = i;
EditorGUILayout.EndHorizontal();
}
if (removeIndex >= 0 && list.Count > 1) list.RemoveAt(removeIndex);
if (GUILayout.Button("+ Add Index")) list.Add(0);
}
private void CreateLightLogicObject(GameObject parentObj)
{
Transform existing = parentObj.transform.Find(newChildObjectName);
if (existing != null)
{
Debug.LogWarning($"'{newChildObjectName}' already exists under '{parentObj.name}'. Skipping.");
return;
}
GameObject newChild = new GameObject(newChildObjectName);
newChild.transform.SetParent(parentObj.transform);
newChild.transform.localPosition = Vector3.zero;
newChild.AddComponent<ChangeLightColour>();
Debug.Log($"✅ Created '{newChildObjectName}' with ChangeLightColour under '{parentObj.name}'");
ReplaceFieldsOnExistingLightLogic(parentObj);
}
private void ReplaceFieldsOnExistingLightLogic(GameObject targetObj)
{
Transform lightLogicTransform = targetObj.transform.Find(newChildObjectName);
if (lightLogicTransform == null)
{
Debug.LogWarning($"No '{newChildObjectName}' child found under '{targetObj.name}'. Skipping.");
return;
}
ChangeLightColour lightLogic = lightLogicTransform.GetComponent<ChangeLightColour>();
if (lightLogic == null)
{
Debug.LogWarning($"'{newChildObjectName}' exists but has no ChangeLightColour script.");
return;
}
SerializedObject so = new SerializedObject(lightLogic);
if (lampRendererMaterial != null)
so.FindProperty("_lampRendererMaterial").objectReferenceValue = lampRendererMaterial;
if (lightRendererMaterial != null)
so.FindProperty("_lightRendererMaterial").objectReferenceValue = lightRendererMaterial;
so.FindProperty("_lightColour").colorValue = lightColour;
Renderer[] allRenderers = targetObj.GetComponentsInChildren<Renderer>(true);
List<Renderer> newLampRenderers = new List<Renderer>();
List<Renderer> newLightRenderers = new List<Renderer>();
foreach (Renderer rend in allRenderers)
{
bool matchedLamp = false;
foreach (string lampName in lampRendererNames)
{
if (!string.IsNullOrEmpty(lampName) && rend.name == lampName)
{
newLampRenderers.Add(rend);
matchedLamp = true;
break;
}
}
if (!allowSharedRenderers && matchedLamp)
continue;
foreach (string lightName in lightRendererNames)
{
if (!string.IsNullOrEmpty(lightName) && rend.name == lightName)
{
newLightRenderers.Add(rend);
break;
}
}
}
Light[] foundLights = targetObj.GetComponentsInChildren<Light>(true);
List<Light> activeLights = new List<Light>();
foreach (var light in foundLights)
{
if (!onlyActiveLights || light.gameObject.activeSelf)
activeLights.Add(light);
}
SetArrayProperty(so.FindProperty("_lampRenderer"), newLampRenderers.ToArray());
SetArrayProperty(so.FindProperty("_lightRend"), newLightRenderers.ToArray());
SetArrayProperty(so.FindProperty("_light"), activeLights.ToArray());
SetIntArrayProperty(so.FindProperty("_lampRendererMaterialIndices"), lampMaterialIndices.ToArray());
SetIntArrayProperty(so.FindProperty("_lightRendererMaterialIndices"), lightMaterialIndices.ToArray());
var lightData = targetObj.GetComponent<LightInteractableData>();
if (lightData != null)
{
so.FindProperty("lightInteractableData").objectReferenceValue = lightData;
}
so.ApplyModifiedProperties();
Debug.Log($"🔁 Updated ChangeLightColour fields on '{lightLogic.gameObject.name}'");
}
private void SetArrayProperty<T>(SerializedProperty property, T[] values) where T : Object
{
property.arraySize = values.Length;
for (int i = 0; i < values.Length; i++)
{
property.GetArrayElementAtIndex(i).objectReferenceValue = values[i];
}
}
private void SetIntArrayProperty(SerializedProperty property, int[] values)
{
property.arraySize = values.Length;
for (int i = 0; i < values.Length; i++)
{
property.GetArrayElementAtIndex(i).intValue = values[i];
}
}
private void LoadPreset(LightSetupPreset preset)
{
newChildObjectName = preset.newChildObjectName;
lampRendererNames = new List<string>(preset.lampRendererNames);
lightRendererNames = new List<string>(preset.lightRendererNames);
lampRendererMaterial = preset.lampRendererMaterial;
lightRendererMaterial = preset.lightRendererMaterial;
lightColour = preset.lightColour;
lampMaterialIndices = new List<int>(preset.lampMaterialIndices);
lightMaterialIndices = new List<int>(preset.lightMaterialIndices);
onlyActiveLights = preset.onlyActiveLights;
}
private void SaveCurrentToPreset(LightSetupPreset preset)
{
preset.newChildObjectName = newChildObjectName;
preset.lampRendererNames = new List<string>(lampRendererNames);
preset.lightRendererNames = new List<string>(lightRendererNames);
preset.lampRendererMaterial = lampRendererMaterial;
preset.lightRendererMaterial = lightRendererMaterial;
preset.lightColour = lightColour;
preset.lampMaterialIndices = new List<int>(lampMaterialIndices);
preset.lightMaterialIndices = new List<int>(lightMaterialIndices);
preset.onlyActiveLights = onlyActiveLights;
}
}