using System.Collections.Generic; using UnityEditor; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.SceneManagement; namespace Streamingle.Background.Editor { /// /// 배경 씬에서 라이팅 세팅을 복사해오는 유틸리티 /// public static class BackgroundLightingCopier { /// /// 소스 씬에서 타겟 씬으로 라이팅 세팅 복사 /// public static void CopyLightingSettings(Scene sourceScene, Scene targetScene) { if (!sourceScene.isLoaded || !targetScene.isLoaded) { UnityEngine.Debug.LogWarning("소스 씬 또는 타겟 씬이 로드되지 않았습니다."); return; } // 1. Environment 설정 복사 (Skybox, Ambient, Fog 등) CopyEnvironmentSettings(); // 2. 소스 씬의 라이트들을 타겟 씬으로 복사 CopyLights(sourceScene, targetScene); // 3. Reflection Probe 복사 CopyReflectionProbes(sourceScene, targetScene); // 4. Light Probe Group 복사 CopyLightProbeGroups(sourceScene, targetScene); // 5. Volume (Post Processing) 복사 CopyVolumes(sourceScene, targetScene); UnityEngine.Debug.Log($"라이팅 세팅 복사 완료: {sourceScene.name} → {targetScene.name}"); } /// /// 현재 활성 씬에 배경 씬의 라이팅 적용 /// public static void ApplyLightingFromBackgroundScene(Scene backgroundScene) { if (!backgroundScene.isLoaded) { UnityEngine.Debug.LogWarning("배경 씬이 로드되지 않았습니다."); return; } // Environment 설정 복사 CopyEnvironmentSettingsFromScene(backgroundScene); UnityEngine.Debug.Log($"라이팅 세팅 적용됨: {backgroundScene.name}"); } private static void CopyEnvironmentSettings() { // RenderSettings는 현재 활성 씬에 적용됨 // Lighting Window에서 설정하는 것들 } private static void CopyEnvironmentSettingsFromScene(Scene sourceScene) { // 소스 씬을 활성 씬으로 설정하여 RenderSettings 가져오기 var previousActiveScene = SceneManager.GetActiveScene(); // 소스 씬에서 Environment 관련 오브젝트 찾기 var rootObjects = sourceScene.GetRootGameObjects(); foreach (var obj in rootObjects) { // Directional Light (Sun) 찾기 var lights = obj.GetComponentsInChildren(true); foreach (var light in lights) { if (light.type == LightType.Directional) { // Sun Source로 설정 RenderSettings.sun = light; break; } } // Volume 찾기 (Global Volume의 경우 환경 설정 포함) var volumes = obj.GetComponentsInChildren(true); foreach (var volume in volumes) { if (volume.isGlobal && volume.sharedProfile != null) { // Global Volume의 프로파일에서 환경 설정 복사 가능 } } } } private static void CopyLights(Scene sourceScene, Scene targetScene) { var sourceRoots = sourceScene.GetRootGameObjects(); var lightsContainer = GetOrCreateLightingContainer(targetScene, "Background Lights"); foreach (var root in sourceRoots) { var lights = root.GetComponentsInChildren(true); foreach (var light in lights) { // 라이트 복제 var newLightObj = Object.Instantiate(light.gameObject, lightsContainer.transform); newLightObj.name = $"[BG] {light.gameObject.name}"; // 씬 이동 SceneManager.MoveGameObjectToScene(newLightObj, targetScene); } } } private static void CopyReflectionProbes(Scene sourceScene, Scene targetScene) { var sourceRoots = sourceScene.GetRootGameObjects(); var container = GetOrCreateLightingContainer(targetScene, "Background ReflectionProbes"); foreach (var root in sourceRoots) { var probes = root.GetComponentsInChildren(true); foreach (var probe in probes) { var newProbeObj = Object.Instantiate(probe.gameObject, container.transform); newProbeObj.name = $"[BG] {probe.gameObject.name}"; SceneManager.MoveGameObjectToScene(newProbeObj, targetScene); } } } private static void CopyLightProbeGroups(Scene sourceScene, Scene targetScene) { var sourceRoots = sourceScene.GetRootGameObjects(); var container = GetOrCreateLightingContainer(targetScene, "Background LightProbes"); foreach (var root in sourceRoots) { var groups = root.GetComponentsInChildren(true); foreach (var group in groups) { var newGroupObj = Object.Instantiate(group.gameObject, container.transform); newGroupObj.name = $"[BG] {group.gameObject.name}"; SceneManager.MoveGameObjectToScene(newGroupObj, targetScene); } } } private static void CopyVolumes(Scene sourceScene, Scene targetScene) { var sourceRoots = sourceScene.GetRootGameObjects(); var container = GetOrCreateLightingContainer(targetScene, "Background Volumes"); foreach (var root in sourceRoots) { var volumes = root.GetComponentsInChildren(true); foreach (var volume in volumes) { var newVolumeObj = Object.Instantiate(volume.gameObject, container.transform); newVolumeObj.name = $"[BG] {volume.gameObject.name}"; SceneManager.MoveGameObjectToScene(newVolumeObj, targetScene); } } } private static GameObject GetOrCreateLightingContainer(Scene scene, string name) { var roots = scene.GetRootGameObjects(); // 기존 컨테이너 찾기 foreach (var root in roots) { if (root.name == name) { // 기존 자식들 제거 while (root.transform.childCount > 0) { Object.DestroyImmediate(root.transform.GetChild(0).gameObject); } return root; } } // 새 컨테이너 생성 var container = new GameObject(name); SceneManager.MoveGameObjectToScene(container, scene); return container; } /// /// 타겟 씬에서 복사된 라이팅 오브젝트들 제거 /// public static void RemoveCopiedLighting(Scene targetScene) { var roots = targetScene.GetRootGameObjects(); var toRemove = new List(); foreach (var root in roots) { if (root.name.StartsWith("Background ") || root.name.StartsWith("[BG]")) { toRemove.Add(root); } } foreach (var obj in toRemove) { Object.DestroyImmediate(obj); } UnityEngine.Debug.Log($"복사된 라이팅 오브젝트 제거됨: {toRemove.Count}개"); } /// /// 배경 씬의 Skybox Material 가져오기 /// public static Material GetSkyboxFromScene(Scene scene) { var roots = scene.GetRootGameObjects(); foreach (var root in roots) { // Skybox 컴포넌트가 있는 카메라 찾기 var cameras = root.GetComponentsInChildren(true); foreach (var cam in cameras) { var skybox = cam.GetComponent(); if (skybox != null && skybox.material != null) { return skybox.material; } } } return null; } /// /// RenderSettings 전체 복사 (Skybox, Ambient, Fog 등) /// public static void ApplyRenderSettings( Material skybox = null, AmbientMode? ambientMode = null, Color? ambientLight = null, bool? fog = null, Color? fogColor = null, float? fogDensity = null) { if (skybox != null) RenderSettings.skybox = skybox; if (ambientMode.HasValue) RenderSettings.ambientMode = ambientMode.Value; if (ambientLight.HasValue) RenderSettings.ambientLight = ambientLight.Value; if (fog.HasValue) RenderSettings.fog = fog.Value; if (fogColor.HasValue) RenderSettings.fogColor = fogColor.Value; if (fogDensity.HasValue) RenderSettings.fogDensity = fogDensity.Value; } } }