312 lines
12 KiB
C#
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;
|
|
}
|
|
}
|