Project_WL/Assets/WL/Look/Farm/WLFarmLook.cs

125 lines
5.9 KiB
C#

// ─────────────────────────────────────────────────────────────────────────────
// WLFarmLook.cs — WL_FarmLook 씬의 되돌리기 스위치 (WL-816a · #816)
//
// 씬에는 **통일 룩(Toon · 텍스처 유지안)이 이미 저장돼 있다**. 이 컴포넌트는
// · `enabled_ = 0` → 저장해 둔 FarmingIsland 원본 머티리얼·원본 조명으로 100 % 되돌린다
// · `mode = 2` → 단색안 머티리얼로 갈아끼운다(비교용)
// 만 한다. 에셋(FarmingIsland 원본 머티리얼·프리팹·씬)은 **한 글자도 안 바꾼다**.
//
// 🔴 Debug.LogError / Debug.LogException 을 쓰지 않는다(813z 규칙).
// ─────────────────────────────────────────────────────────────────────────────
using UnityEngine;
using UnityEngine.Rendering;
namespace WL.Look.Farm
{
[DisallowMultipleComponent]
public class WLFarmLook : MonoBehaviour
{
public static string LastLog = "";
public static int AppliedMode = -1;
// ── 렌더러별 3세트(원본 / 텍스처 유지 / 단색) ─────────────────────
[System.Serializable]
public sealed class Entry
{
public Renderer target;
public Material[] original;
public Material[] toonTex;
public Material[] toonFlat;
}
[Tooltip("씬 빌드 스크립트가 채운다. 렌더러 1개당 1줄.")]
public Entry[] entries = new Entry[0];
// ── 원본 조명(되돌리기용) ─────────────────────────────────────────
[System.Serializable]
public sealed class LightState
{
public Light target;
public Color color = Color.white;
public float intensity = 1f;
public LightShadows shadows = LightShadows.Hard;
}
[Header("원본 조명 (enabled_=0 일 때 되돌릴 값)")]
public LightState[] originalLights = new LightState[0];
public int origAmbientMode = 3; // 3 = Flat
public Color origAmbientSky = Color.gray;
public Color origAmbientEquator = Color.gray;
public Color origAmbientGround = Color.gray;
public float origAmbientIntensity = 1f;
public Material origSkybox;
public int origReflectionMode = 1; // 1 = Custom
public Light origSun;
void Awake()
{
var cfg = WLFarmLookSettings.Instance;
int mode = cfg == null ? 1 : (cfg.enabled_ == 0 ? 0 : cfg.mode);
Apply(mode, cfg == null || cfg.enabled_ != 0 ? (cfg == null ? 1 : cfg.applyLighting) : 0);
if (cfg != null && cfg.verboseLog != 0) Debug.Log("[WL816a FarmLook] " + LastLog);
}
/// <summary>
/// `enabled_ = 0` 이면 같은 씬의 `WL_ReferenceLook`(아레나 룩)도 함께 끈다.
/// Start 는 모든 Awake/OnEnable 뒤에 돌기 때문에 실행 순서에 상관없이 확실히 원복된다.
/// </summary>
void Start()
{
var cfg = WLFarmLookSettings.Instance;
if (cfg == null || cfg.enabled_ != 0) return;
var rl = Object.FindFirstObjectByType<WL.Look.Arena.WLReferenceLook>(FindObjectsInactive.Include);
if (rl != null && rl.gameObject.activeSelf) rl.gameObject.SetActive(false); // OnDisable → Restore()
WL.Look.Arena.WLReferenceLook.Restore();
Apply(0, 0);
LastLog += " · ReferenceLook 도 off";
}
/// <summary>0 = 원본 · 1 = 텍스처 유지 · 2 = 단색. 몇 번 불러도 안전(멱등).</summary>
public void Apply(int mode, int applyLighting)
{
int n = 0;
for (int i = 0; i < entries.Length; i++)
{
var e = entries[i];
if (e == null || e.target == null) continue;
Material[] set = mode == 0 ? e.original : (mode == 2 ? e.toonFlat : e.toonTex);
if (set == null || set.Length == 0) set = e.original;
if (set == null || set.Length == 0) continue;
e.target.sharedMaterials = set;
n++;
}
if (applyLighting == 0) RestoreLighting();
AppliedMode = mode;
LastLog = "mode=" + mode + "(" + (mode == 0 ? "원본" : mode == 2 ? "단색" : "텍스처유지")
+ ") 렌더러 " + n + " · lighting=" + (applyLighting == 0 ? "원본" : "데모/아레나");
}
/// <summary>FarmingIsland 원본 조명·앰비언트·스카이박스로 되돌린다.</summary>
public void RestoreLighting()
{
for (int i = 0; i < originalLights.Length; i++)
{
var s = originalLights[i];
if (s == null || s.target == null) continue;
s.target.color = s.color;
s.target.intensity = s.intensity;
s.target.shadows = s.shadows;
}
RenderSettings.ambientMode = (AmbientMode)origAmbientMode;
RenderSettings.ambientSkyColor = origAmbientSky;
RenderSettings.ambientEquatorColor = origAmbientEquator;
RenderSettings.ambientGroundColor = origAmbientGround;
RenderSettings.ambientLight = origAmbientSky;
RenderSettings.ambientIntensity = origAmbientIntensity;
if (origSkybox != null) RenderSettings.skybox = origSkybox;
RenderSettings.defaultReflectionMode = (DefaultReflectionMode)origReflectionMode;
RenderSettings.sun = origSun;
}
}
}