diff --git a/AgentScripts/WL816h_BUILD.txt b/AgentScripts/WL816h_BUILD.txt new file mode 100644 index 000000000..9178eaa49 --- /dev/null +++ b/AgentScripts/WL816h_BUILD.txt @@ -0,0 +1,6 @@ +원본 Assets/WL/Materials/WL_Water_Ocean.mat shader=Shader Graphs/ToonWaterU +복사 Assets/WL/Look/Farm/Materials/Farm_Water_WL_A.mat = Shader Graphs/ToonWaterU +복사 Assets/WL/Look/Farm/Materials/Farm_Water_WL_B.mat = Shader Graphs/ToonWaterU +복사 Assets/WL/Look/Farm/Materials/Farm_Water_WL_C.mat = Shader Graphs/ToonWaterU +FI 원본 물 = Assets/FarmingIsland/Materials/Environments/SimpleWater.mat +SO 배선 완료 — waterMode=1 waterTo=Farm_Water_WL_B skyScopeEnabled=1 skyScenes=Level01,WL_FarmLook,WL_Dungeon01,WL_Dungeon02 diff --git a/AgentScripts/WL816h_CONSOLE.txt b/AgentScripts/WL816h_CONSOLE.txt new file mode 100644 index 000000000..4e7aab0d6 --- /dev/null +++ b/AgentScripts/WL816h_CONSOLE.txt @@ -0,0 +1,22 @@ +error=6 warning=408 log=1398 +--- error 메시지(중복 묶음) --- + ×1 PlayFabException: Must be logged in to call this method + PlayFab.PlayFabClientAPI.GetTitleNews (PlayFab.ClientModels.GetTitleNewsRequest request, System.Action`1[T] resultCallba + ServerInfo.Get_News (System.Action`1[T] _act) (at Assets/Script/Server/ServerInfo.cs:428) + DataCheckMgr+d__11.MoveNext () (at Assets/Script/Util/DataCheckMgr.cs:38) + ×1 NullReferenceException: Object reference not set to an instance of an object + DataCheckMgr+d__13.MoveNext () (at Assets/Script/Util/DataCheckMgr.cs:59) + UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) + UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator) + ×1 NullReferenceException: Object reference not set to an instance of an object + InGameInfo.Set_Init () (at Assets/Script/Info/InGameInfo.cs:46) + InGameInfo+d__16.MoveNext () (at Assets/Script/Info/InGameInfo.cs:78) + UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) + ×1 NullReferenceException: Object reference not set to an instance of an object + ProjectileInfo+d__7.MoveNext () (at Assets/Script/Info/ProjectileInfo.cs:33) + UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) + ×1 NullReferenceException: Object reference not set to an instance of an object + DropItemInfo.Make_DropItem (System.Int32 key, System.Int32 count) (at Assets/Script/Info/DropItemInfo.cs:60) + DropItemInfo.Start () (at Assets/Script/Info/DropItemInfo.cs:24) + ×1 NullReferenceException: Object reference not set to an instance of an object + LoadMapMgr.Awake () (at Assets/Script/Ingame/LoadMapMgr.cs:16) diff --git a/AgentScripts/WL816h_CONSOLE_off.txt b/AgentScripts/WL816h_CONSOLE_off.txt new file mode 100644 index 000000000..02d30a845 --- /dev/null +++ b/AgentScripts/WL816h_CONSOLE_off.txt @@ -0,0 +1,22 @@ +error=6 warning=410 log=4139 +--- error 메시지(중복 묶음) --- + ×1 NullReferenceException: Object reference not set to an instance of an object + ProjectileInfo+d__7.MoveNext () (at Assets/Script/Info/ProjectileInfo.cs:33) + UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) + ×1 PlayFabException: Must be logged in to call this method + PlayFab.PlayFabClientAPI.GetTitleNews (PlayFab.ClientModels.GetTitleNewsRequest request, System.Action`1[T] resultCallba + ServerInfo.Get_News (System.Action`1[T] _act) (at Assets/Script/Server/ServerInfo.cs:428) + DataCheckMgr+d__11.MoveNext () (at Assets/Script/Util/DataCheckMgr.cs:38) + ×1 NullReferenceException: Object reference not set to an instance of an object + DataCheckMgr+d__13.MoveNext () (at Assets/Script/Util/DataCheckMgr.cs:59) + UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) + UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator) + ×1 NullReferenceException: Object reference not set to an instance of an object + InGameInfo.Set_Init () (at Assets/Script/Info/InGameInfo.cs:46) + InGameInfo+d__16.MoveNext () (at Assets/Script/Info/InGameInfo.cs:78) + UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) + ×1 NullReferenceException: Object reference not set to an instance of an object + DropItemInfo.Make_DropItem (System.Int32 key, System.Int32 count) (at Assets/Script/Info/DropItemInfo.cs:60) + DropItemInfo.Start () (at Assets/Script/Info/DropItemInfo.cs:24) + ×1 NullReferenceException: Object reference not set to an instance of an object + LoadMapMgr.Awake () (at Assets/Script/Ingame/LoadMapMgr.cs:16) diff --git a/AgentScripts/WL816h_Console.cs b/AgentScripts/WL816h_Console.cs new file mode 100644 index 000000000..7f1129422 --- /dev/null +++ b/AgentScripts/WL816h_Console.cs @@ -0,0 +1,58 @@ +// WL-816h — 콘솔 error/warning 수와 error 메시지만 뽑아 파일로 (토큰 절약) +using System.Reflection; +using UnityEngine; + +public static class WL816h_Console +{ + public static void Dump() + { + var t = System.Type.GetType("UnityEditor.LogEntries,UnityEditor"); + var sb = new System.Text.StringBuilder(); + object[] args = { 0, 0, 0 }; + t.GetMethod("GetCountsByType", BindingFlags.Public | BindingFlags.Static).Invoke(null, args); + sb.AppendLine("error=" + args[0] + " warning=" + args[1] + " log=" + args[2]); + + int n = (int)t.GetMethod("StartGettingEntries", BindingFlags.Public | BindingFlags.Static).Invoke(null, null); + var entryType = System.Type.GetType("UnityEditor.LogEntry,UnityEditor"); + var entry = System.Activator.CreateInstance(entryType); + var getEntry = t.GetMethod("GetEntryInternal", BindingFlags.Public | BindingFlags.Static); + var msgF = entryType.GetField("message", BindingFlags.Public | BindingFlags.Instance); + var modeF = entryType.GetField("mode", BindingFlags.Public | BindingFlags.Instance); + var seen = new System.Collections.Generic.Dictionary(); + for (int i = 0; i < n; i++) + { + object[] a2 = { i, entry }; + getEntry.Invoke(null, a2); + int mode = (int)modeF.GetValue(a2[1]); + // Error(1) | Assert(2) | Fatal(0x10) | ScriptingError(0x100) | ScriptingException(0x400) | ScriptCompileError(0x800) + bool isErr = (mode & (1 | 2 | 0x10 | 0x100 | 0x400 | 0x800 | 0x2000)) != 0; + if (!isErr) continue; + string m = (string)msgF.GetValue(a2[1]); + if (m == null) continue; + // 메시지 1줄 + 스택 앞 3줄 (누가 냈는지 보려고) + var lines = m.Split('\n'); + var key = new System.Text.StringBuilder(lines[0].Length > 140 ? lines[0].Substring(0, 140) : lines[0]); + for (int k = 1; k < lines.Length && k <= 3; k++) + { + var s = lines[k].Trim(); + if (s.Length == 0) continue; + if (s.Length > 120) s = s.Substring(0, 120); + key.Append("\n ").Append(s); + } + string kk = key.ToString(); + seen[kk] = seen.ContainsKey(kk) ? seen[kk] + 1 : 1; + } + t.GetMethod("EndGettingEntries", BindingFlags.Public | BindingFlags.Static).Invoke(null, null); + sb.AppendLine("--- error 메시지(중복 묶음) ---"); + foreach (var kv in seen) sb.AppendLine(" ×" + kv.Value + " " + kv.Key); + if (seen.Count == 0) sb.AppendLine(" (없음)"); + System.IO.File.WriteAllText("AgentScripts/WL816h_CONSOLE.txt", sb.ToString()); + Debug.Log("[816h console]\n" + sb); + } + + public static void Clear() + { + var t = System.Type.GetType("UnityEditor.LogEntries,UnityEditor"); + t.GetMethod("Clear", BindingFlags.Public | BindingFlags.Static).Invoke(null, null); + } +} diff --git a/AgentScripts/WL816h_DEMO.txt b/AgentScripts/WL816h_DEMO.txt new file mode 100644 index 000000000..5fd79be77 --- /dev/null +++ b/AgentScripts/WL816h_DEMO.txt @@ -0,0 +1,2 @@ +데모 = #647676 → Screenshots_WL/WL816h/x_demo_horizon.png +나란히 = Screenshots_WL/WL816h/d_demo_vs_island.png (좌 데모 / 우 우리 섬 · 같은 화각) diff --git a/AgentScripts/WL816h_Demo.cs b/AgentScripts/WL816h_Demo.cs new file mode 100644 index 000000000..e6840dcf0 --- /dev/null +++ b/AgentScripts/WL816h_Demo.cs @@ -0,0 +1,81 @@ +// WL-816h — ⓓ 데모 씬과 나란히 (에디트 모드 렌더 · §9 데모 Play 안 함) +using UnityEngine; +using UnityEngine.Rendering.Universal; +using UnityEditor; + +public static class WL816h_Demo +{ + const string Dir = "Screenshots_WL/WL816h/"; + const int W = 1080, H = 1920; + + public static void Run() + { + var sb = new System.Text.StringBuilder(); + UnityEditor.SceneManagement.EditorSceneManager.OpenScene( + "Assets/LowPolyFantasyArena/Scenes/LowPolyArena_Demo.unity", + UnityEditor.SceneManagement.OpenSceneMode.Single); + + // 수평선이 보이는 화각 — 우리 섬 캡처(b_after_horizon)와 같은 fov·피치 + var go = new GameObject("~WL816hDemoCam"); go.hideFlags = HideFlags.DontSave; + var c = go.AddComponent(); + c.orthographic = false; c.fieldOfView = 55f; c.nearClipPlane = 0.3f; c.farClipPlane = 2000f; + c.clearFlags = CameraClearFlags.Skybox; c.cullingMask = ~0; c.depth = -100f; + go.transform.position = new Vector3(-14f, 8f, -14f); + go.transform.rotation = Quaternion.Euler(4f, 45f, 0f); + go.AddComponent(); + + sb.AppendLine("데모 = " + Shot(c, Dir + "x_demo_horizon.png")); + Object.DestroyImmediate(go); + + Pair(Dir + "x_demo_horizon.png", Dir + "b_after_horizon.png", Dir + "d_demo_vs_island.png"); + sb.AppendLine("나란히 = " + Dir + "d_demo_vs_island.png (좌 데모 / 우 우리 섬 · 같은 화각)"); + System.IO.File.WriteAllText("AgentScripts/WL816h_DEMO.txt", sb.ToString()); + Debug.Log("[816h demo]\n" + sb); + + // 다음 작업을 위해 InGame 으로 돌려 둔다(데모 씬 저장 0) + UnityEditor.SceneManagement.EditorSceneManager.OpenScene( + "Assets/Scenes/InGame.unity", UnityEditor.SceneManagement.OpenSceneMode.Single); + } + + static string Shot(Camera cam, string path) + { + System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(path)); + var rt = new RenderTexture(W, H, 24, RenderTextureFormat.ARGB32, RenderTextureReadWrite.sRGB); + rt.antiAliasing = 1; rt.Create(); + var pA = RenderTexture.active; + cam.targetTexture = rt; cam.Render(); RenderTexture.active = rt; + var tex = new Texture2D(W, H, TextureFormat.RGB24, false); + tex.ReadPixels(new Rect(0, 0, W, H), 0, 0); tex.Apply(); + RenderTexture.active = pA; cam.targetTexture = null; + System.IO.File.WriteAllBytes(path, tex.EncodeToPNG()); + var px = tex.GetPixels32(); long r = 0, g = 0, b = 0; + for (int i = 0; i < px.Length; i += 7) { r += px[i].r; g += px[i].g; b += px[i].b; } + int n = (px.Length + 6) / 7; + Object.DestroyImmediate(tex); rt.Release(); Object.DestroyImmediate(rt); + return "#" + ((int)(r / n)).ToString("X2") + ((int)(g / n)).ToString("X2") + ((int)(b / n)).ToString("X2") + " → " + path; + } + + static void Pair(string left, string right, string outPath) + { + var a = Load(left); var b = Load(right); + if (a == null || b == null) { Debug.Log("[816h] 나란히 실패 " + left + " / " + right); return; } + int w = a.width + b.width, h = Mathf.Max(a.height, b.height); + var o = new Texture2D(w, h, TextureFormat.RGB24, false); + var fill = new Color32[w * h]; + for (int i = 0; i < fill.Length; i++) fill[i] = new Color32(24, 24, 28, 255); + o.SetPixels32(fill); + o.SetPixels32(0, 0, a.width, a.height, a.GetPixels32()); + o.SetPixels32(a.width, 0, b.width, b.height, b.GetPixels32()); + o.Apply(); + System.IO.File.WriteAllBytes(outPath, o.EncodeToPNG()); + Object.DestroyImmediate(o); Object.DestroyImmediate(a); Object.DestroyImmediate(b); + } + + static Texture2D Load(string p) + { + if (!System.IO.File.Exists(p)) return null; + var t = new Texture2D(2, 2, TextureFormat.RGB24, false); + t.LoadImage(System.IO.File.ReadAllBytes(p)); + return t; + } +} diff --git a/AgentScripts/WL816h_FUNC.txt b/AgentScripts/WL816h_FUNC.txt new file mode 100644 index 000000000..1b88c23cd --- /dev/null +++ b/AgentScripts/WL816h_FUNC.txt @@ -0,0 +1,8 @@ +=== ⑥ 기능 무영향 (PD 경로 · 채택 상태) === +물 : mat=Farm_Water_WL_C · MeshCollider=있음 enabled=True mesh=Plane · MeshFilter=Plane · layer=0 · pos=(0.0, -1.0, 0.0) · scale=(100, 1, 100) +걷기: (0.00, 0.00, 0.00) → (4.24, 0.01, 4.24) · 이동 6.00 m · grounded=True +풀(확장 전): 타일 5 · 인스턴스 680 · 드로우콜 2 · 삼각형 6111 · 제외점 358 · 밀도 1.80(=3.24개/㎡) · 섬 타일 5 +풀(1칸 잠금): 타일 4 · 인스턴스 602 · 드로우콜 2 · 삼각형 5409 · 제외점 240 · 밀도 1.80(=3.24개/㎡) +풀(다시 열기): 타일 5 · 인스턴스 699 · 드로우콜 2 · 삼각형 6282 · 제외점 339 · 밀도 1.80(=3.24개/㎡) · 재생성 2회 +최종 = Screenshots_WL/WL816h/b_final_pd_path.png +SkyScope held=True · held(Level01) → amb=Skybox light=(0.212,0.227,0.259) skybox=Default-Skybox fog=False refl=Skybox sun=DirectionalLight diff --git a/AgentScripts/WL816h_Func.cs b/AgentScripts/WL816h_Func.cs new file mode 100644 index 000000000..c1bf0ce6f --- /dev/null +++ b/AgentScripts/WL816h_Func.cs @@ -0,0 +1,115 @@ +// WL-816h — ⑥ 기능 무영향 실측 (걷기 · 섬 확장 · 물 콜라이더) + 최종 PD 경로 캡처 +using System.Collections; +using UnityEngine; +using UnityEngine.SceneManagement; +using UnityEngine.Rendering.Universal; +using FIIsland = CryingSnow.FarmingIsland.Island; + +public static class WL816h_Func +{ + public static void Open() + { + UnityEditor.SceneManagement.EditorSceneManager.OpenScene( + "Assets/Scenes/InGame.unity", UnityEditor.SceneManagement.OpenSceneMode.Single); + } + public static void Start() + { + var go = GameObject.Find("~WL816hFunc"); + if (go != null) Object.DestroyImmediate(go); + go = new GameObject("~WL816hFunc"); + go.AddComponent(); + } +} + +public class WL816h_FuncRunner : MonoBehaviour +{ + static System.Text.StringBuilder sb; + static void L(string s) { sb.AppendLine(s); } + + void Start() { StartCoroutine(Co()); } + + IEnumerator Co() + { + sb = new System.Text.StringBuilder(); + L("=== ⑥ 기능 무영향 (PD 경로 · 채택 상태) ==="); + var op = SceneManager.LoadSceneAsync("Level01", LoadSceneMode.Additive); + while (op != null && !op.isDone) yield return null; + for (int i = 0; i < 7; i++) yield return new WaitForSeconds(1f); + + // 물 — 콜라이더·메시가 그대로인가 (머티리얼만 바꿨다) + Renderer water = null; + foreach (var r in Object.FindObjectsByType(FindObjectsInactive.Exclude, FindObjectsSortMode.None)) + if (r != null && r.gameObject.scene.name == "Level01" && r.name == "Water") water = r; + if (water != null) + { + var mc = water.GetComponent(); + var mf = water.GetComponent(); + L("물 : mat=" + water.sharedMaterial.name + " · MeshCollider=" + (mc != null ? ("있음 enabled=" + mc.enabled + " mesh=" + (mc.sharedMesh ? mc.sharedMesh.name : "없음")) : "없음") + + " · MeshFilter=" + (mf != null && mf.sharedMesh ? mf.sharedMesh.name : "없음") + + " · layer=" + water.gameObject.layer + " · pos=" + water.transform.position.ToString("F1") + + " · scale=" + water.transform.localScale.ToString("F0")); + } + + // 걷기 — FI 플레이어의 CharacterController 로 대각선 6 m + var cc = Object.FindFirstObjectByType(FindObjectsInactive.Exclude); + if (cc != null) + { + var p0 = cc.transform.position; + var dir = new Vector3(1f, 0f, 1f).normalized; + float moved = 0f; + for (int i = 0; i < 120 && moved < 6f; i++) + { cc.Move(dir * 0.05f + Vector3.down * 0.05f); moved += 0.05f; yield return null; } + var p1 = cc.transform.position; + L("걷기: " + p0.ToString("F2") + " → " + p1.ToString("F2") + + " · 이동 " + Vector3.Distance(new Vector3(p0.x, 0, p0.z), new Vector3(p1.x, 0, p1.z)).ToString("F2") + " m" + + " · grounded=" + cc.isGrounded); + } + else L("걷기: CharacterController 없음(세이브 상태에 따라 없을 수 있다)"); + + // 섬 확장 — 타일 하나 잠갔다 다시 열기 (풀이 따라오나) + int before = WL.Look.Farm.WLIslandGrass.LastLog != null ? 1 : 0; + var islands = Object.FindObjectsByType(FindObjectsInactive.Exclude, FindObjectsSortMode.None); + L("풀(확장 전): " + WL.Look.Farm.WLIslandGrass.LastLog + " · 섬 타일 " + islands.Length); + FIIsland target = null; + foreach (var isl in islands) if (isl != null && isl.IsUnlocked && isl.gameObject.activeInHierarchy) target = isl; + if (target != null) + { + target.gameObject.SetActive(false); + yield return new WaitForSeconds(2f); + L("풀(1칸 잠금): " + WL.Look.Farm.WLIslandGrass.LastLog); + target.gameObject.SetActive(true); + yield return new WaitForSeconds(3f); + L("풀(다시 열기): " + WL.Look.Farm.WLIslandGrass.LastLog + " · 재생성 " + WL.Look.Farm.WLIslandLook.GrassRebuilds + "회"); + } + + // 최종 PD 경로 캡처 + Camera live = null; + foreach (var c in Object.FindObjectsByType(FindObjectsInactive.Exclude, FindObjectsSortMode.None)) + { + if (!c.gameObject.activeInHierarchy || !c.enabled || c.targetTexture != null) continue; + if (c.name.StartsWith("~WL816h")) continue; + if (live == null || c.depth > live.depth) live = c; + } + L("최종 = " + Shot(live, "Screenshots_WL/WL816h/b_final_pd_path.png")); + L("SkyScope held=" + WL.Look.Farm.WLSkyScope.Held + " · " + WL.Look.Farm.WLSkyScope.LastLog); + + System.IO.File.WriteAllText("AgentScripts/WL816h_FUNC.txt", sb.ToString()); + Debug.Log("[816h func]\n" + sb); + } + + static string Shot(Camera cam, string path) + { + if (cam == null) return "카메라 없음"; + System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(path)); + var rt = new RenderTexture(1080, 1920, 24, RenderTextureFormat.ARGB32, RenderTextureReadWrite.sRGB); + rt.antiAliasing = 1; rt.Create(); + var pT = cam.targetTexture; var pA = RenderTexture.active; + cam.targetTexture = rt; cam.Render(); RenderTexture.active = rt; + var tex = new Texture2D(1080, 1920, TextureFormat.RGB24, false); + tex.ReadPixels(new Rect(0, 0, 1080, 1920), 0, 0); tex.Apply(); + RenderTexture.active = pA; cam.targetTexture = pT; + System.IO.File.WriteAllBytes(path, tex.EncodeToPNG()); + Object.DestroyImmediate(tex); rt.Release(); Object.DestroyImmediate(rt); + return path; + } +} diff --git a/AgentScripts/WL816h_PROBE.txt b/AgentScripts/WL816h_PROBE.txt new file mode 100644 index 000000000..d79df0513 --- /dev/null +++ b/AgentScripts/WL816h_PROBE.txt @@ -0,0 +1,24 @@ +=== WL-816h 지금 상태 (PD 경로 = InGame 활성 + Level01 Additive) === +t0 활성씬=InGame / RenderSettings: amb=Skybox light=(0.212,0.227,0.259) sky=(0.212,0.227,0.259) I=1 skybox=Default-Skybox/Skybox/Procedural fog=False refl=Skybox/1 sun=없음 +Load_Map 예외(=로그인 없이는 못 탄다): NullReferenceException +→ SceneInfo.Load_AddScene 과 같은 호출로 대체: LoadSceneAsync("Level01", Additive) + +t+6s 활성씬=InGame sceneCount=2 +🔴 RenderSettings: amb=Flat light=(0.217,0.228,0.250) sky=(0.217,0.228,0.250) I=1 skybox=Default-Skybox/Skybox/Procedural fog=False refl=Skybox/1 sun=DirectionalLight +IslandLook: 렌더러 1575 light=1 refLook=True +RefLook : applied=True log=Ⓐ17 Ⓑ6mat/md0.12 Ⓒ0.30 Ⓓoff + +CAM Main Camera scene=InGame live=False depth=5 tag=MainCamera clear=Skybox 🔴post=True +CAM MainCamera scene=Level01 live=True depth=-1 tag=MainCamera clear=Skybox 🔴post=True +→ 보이는 카메라 = MainCamera(Level01) +Camera.main = MainCamera(Level01) +Volume Global Volume global=True w=1 prio=0 profile=GlobalVolumeProfile_Blind + +WATER obj=Water layer=0 mat=Farm_SimpleWater_Demo shader=Shader Graphs/Simple Water queue=2999 bounds=(1000, 0, 1000) pos=(0.0, -1.0, 0.0) +WATER obj=WateringCan layer=0 mat=Farm_Palette_ToonTex shader=Shader Graphs/Toon queue=2000 bounds=(1, 1, 1) pos=(0.8, 1.1, 0.0) +WATER obj=WaterParticle layer=0 mat=WaterCan shader=Universal Render Pipeline/Particles/Unlit queue=2450 bounds=(0, 0, 0) pos=(0.0, 0.0, 0.0) +URP asset = URP-Performant opaqueTex=True depthTex=True msaa=1 + +하늘(섬) = #7998B7 → Screenshots_WL/WL816h/a_now_sky.png +섬 화면 = #6FAFD1 → Screenshots_WL/WL816h/a_now_island.png +물 근접 = #80B7C6 → Screenshots_WL/WL816h/a_now_water.png diff --git a/AgentScripts/WL816h_PROBE2.txt b/AgentScripts/WL816h_PROBE2.txt new file mode 100644 index 000000000..4bb35220b --- /dev/null +++ b/AgentScripts/WL816h_PROBE2.txt @@ -0,0 +1,14 @@ +=== ② 「파란 하늘」의 정체 + 섬 나간 뒤 오염 (고치기 전) === +보이는 카메라 = MainCamera fov=60 euler=(45, 0, 0) pos=(0.0, 15.6, -15.6) +물 렌더러 = Water mat=Farm_SimpleWater_Demo shader=Shader Graphs/Simple Water +물 ON = 상단10%=#5BB5FE 하단10%=#5BB5FE → Screenshots_WL/WL816h/a1_water_on.png +물 OFF = 상단10%=#5E4D68 하단10%=#5C4C66 → Screenshots_WL/WL816h/a2_water_off.png + +섬 내리기 전 : amb=Flat light=(0.217,0.228,0.250) skySrc=(0.217,0.228,0.250) I=1 skybox=Default-Skybox fog=False refl=Skybox/1 sun=DirectionalLight +섬 내린 뒤 : amb=Skybox light=(0.212,0.227,0.259) skySrc=(0.212,0.227,0.259) I=1 skybox=Default-Skybox fog=False refl=Skybox/1 sun=없음 +InGame 원본 : amb=Skybox light=(0.212,0.227,0.259) skybox=Default-Skybox fog=False refl=Skybox/1 sun=없음 (씬 파일 실측) +🔴 오염 = 없음(오염 0) + +전투 맵(Map_C01) 올린 뒤 : amb=Skybox light=(0.212,0.227,0.259) skySrc=(0.212,0.227,0.259) I=1 skybox=Default-Skybox fog=False refl=Skybox/1 sun=없음 +🔴 오염 = 없음(오염 0) +전투맵 하늘 = 상단10%=#586773 하단10%=#4D3B1E → Screenshots_WL/WL816h/f0_before_battle_sky.png diff --git a/AgentScripts/WL816h_REF.txt b/AgentScripts/WL816h_REF.txt new file mode 100644 index 000000000..88d6b3b72 --- /dev/null +++ b/AgentScripts/WL816h_REF.txt @@ -0,0 +1,14 @@ +### arena Assets/WL/Look/Arena/Scenes/WL_ArenaProto.unity +RenderSettings: amb=Skybox light=(0.212,0.227,0.259) sky=(0.212,0.227,0.259) I=1 skybox=Default-Skybox/Skybox/Procedural fog=False refl=Skybox/1 sun=Directional Light + CAM PlanarReflectionProbe active=True en=True ortho=True size=5 clear=SolidColor post=False + CAM Main Camera active=True en=True ortho=True size=10 clear=Skybox post=False + Volume 수 = 0 + 하늘 화면색 = #798EA9 → Screenshots_WL/WL816h/ref_sky_arena.png +### demo Assets/LowPolyFantasyArena/Scenes/LowPolyArena_Demo.unity +RenderSettings: amb=Skybox light=(0.212,0.227,0.259) sky=(0.212,0.227,0.259) I=1 skybox=Default-Skybox/Skybox/Procedural fog=False refl=Skybox/1 sun=Directional Light + CAM Camera1 active=True en=True ortho=False fov=60 clear=Skybox post=noACD + CAM Camera2 active=True en=True ortho=False fov=60 clear=Skybox post=noACD + CAM Camera4 active=True en=True ortho=False fov=60 clear=Skybox post=noACD + CAM Camera3 active=True en=True ortho=False fov=60 clear=Skybox post=noACD + Volume 수 = 0 + 하늘 화면색 = #88A4C4 → Screenshots_WL/WL816h/ref_sky_demo.png diff --git a/AgentScripts/WL816h_ROLLBACK_R1.txt b/AgentScripts/WL816h_ROLLBACK_R1.txt new file mode 100644 index 000000000..7a3b7de8c --- /dev/null +++ b/AgentScripts/WL816h_ROLLBACK_R1.txt @@ -0,0 +1,11 @@ +=== 되돌리기 실측 [enabled_=1 skyScope=1 waterMode=1] === +InGame 원래 하늘 : amb=Skybox light=(0.212,0.227,0.259) skySrc=(0.212,0.227,0.259) I=1 skybox=Default-Skybox fog=False refl=Skybox/1 sun=없음 +물 : Farm_Water_WL_C / Shader Graphs/ToonWaterU +머티리얼 교체 : 렌더러 1575 · 물 1 +풀 : 타일 5 · 인스턴스 680 · 드로우콜 2 · 삼각형 6111 · 제외점 358 · 밀도 1.80(=3.24개/㎡) +RefLook : True +SkyScope : held=True acquires=1 restores=0 +섬 하늘 : amb=Flat light=(0.217,0.228,0.250) skySrc=(0.217,0.228,0.250) I=1 skybox=Default-Skybox fog=False refl=Skybox/1 sun=DirectionalLight +화면 : #729AA9 → Screenshots_WL/WL816h/z_rollback_water_now.png +전투 맵 : amb=Skybox light=(0.212,0.227,0.259) skySrc=(0.212,0.227,0.259) I=1 skybox=Default-Skybox fog=False refl=Skybox/1 sun=없음 +🔴 원래대로 = 예 diff --git a/AgentScripts/WL816h_ROLLBACK_R2.txt b/AgentScripts/WL816h_ROLLBACK_R2.txt new file mode 100644 index 000000000..72324f523 --- /dev/null +++ b/AgentScripts/WL816h_ROLLBACK_R2.txt @@ -0,0 +1,11 @@ +=== 되돌리기 실측 [enabled_=0 skyScope=0 waterMode=0] === +InGame 원래 하늘 : amb=Skybox light=(0.212,0.227,0.259) skySrc=(0.212,0.227,0.259) I=1 skybox=Default-Skybox fog=False refl=Skybox/1 sun=없음 +물 : SimpleWater / Shader Graphs/Simple Water +머티리얼 교체 : 렌더러 0 · 물 0 +풀 : +RefLook : False +SkyScope : held=False acquires=0 restores=0 +섬 하늘 : amb=Skybox light=(0.212,0.227,0.259) skySrc=(0.212,0.227,0.259) I=1 skybox=Default-Skybox fog=False refl=Skybox/1 sun=DirectionalLight +화면 : #2891BA → Screenshots_WL/WL816h/z_rollback_off.png +전투 맵 : amb=Skybox light=(0.212,0.227,0.259) skySrc=(0.212,0.227,0.259) I=1 skybox=Default-Skybox fog=False refl=Skybox/1 sun=없음 +🔴 원래대로 = 예 diff --git a/AgentScripts/WL816h_Rollback.cs b/AgentScripts/WL816h_Rollback.cs new file mode 100644 index 000000000..b3211669e --- /dev/null +++ b/AgentScripts/WL816h_Rollback.cs @@ -0,0 +1,131 @@ +// WL-816h — ⑤ 되돌리기 실측 (SO 스위치 하나로 100 % 복귀) +// R1 = waterMode 0 + skyScopeEnabled 0 → 816f 상태(FarmingIsland 물 · 스코프 없음) +// R2 = enabled_ 0 → 섬 룩 전체 off (816e/816f 가 쓰던 스위치) +using System.Collections; +using UnityEngine; +using UnityEngine.SceneManagement; +using UnityEditor; + +public static class WL816h_Rollback +{ + const string SO = "Assets/WL/Look/Farm/Resources/WL/WLIslandLookSettings.asset"; + const string Dir = "Screenshots_WL/WL816h/"; + + public static void SetR1() { Set(1, 0, 0); } // 섬 룩은 그대로 · 물/스코프만 끈다 + public static void SetR2() { Set(0, 0, 0); } // 전부 off + public static void SetOn() { Set(1, 1, 1); } // 채택 상태로 복귀 + + static void Set(int enabled_, int sky, int water) + { + var so = AssetDatabase.LoadAssetAtPath(SO); + if (so == null) { Debug.Log("[816h] SO 없음"); return; } + so.enabled_ = enabled_; so.skyScopeEnabled = sky; so.waterMode = water; + EditorUtility.SetDirty(so); AssetDatabase.SaveAssets(); + WL.Look.Farm.WLIslandLookSettings.Invalidate(); + Debug.Log("[816h] SO enabled_=" + enabled_ + " skyScope=" + sky + " waterMode=" + water); + UnityEditor.SceneManagement.EditorSceneManager.OpenScene( + "Assets/Scenes/InGame.unity", UnityEditor.SceneManagement.OpenSceneMode.Single); + } + + public static void Start() + { + var go = GameObject.Find("~WL816hRollback"); + if (go != null) Object.DestroyImmediate(go); + go = new GameObject("~WL816hRollback"); + go.AddComponent(); + } +} + +/// run_script 는 파일 하나만 컴파일한다 → 도우미를 여기에 그대로 둔다. +public static class RB +{ + public const int W = 1080, H = 1920; + + public static string Sky() + { + return "amb=" + RenderSettings.ambientMode + " light=" + F(RenderSettings.ambientLight) + + " skySrc=" + F(RenderSettings.ambientSkyColor) + " I=" + RenderSettings.ambientIntensity + + " skybox=" + (RenderSettings.skybox ? RenderSettings.skybox.name : "없음") + + " fog=" + RenderSettings.fog + " refl=" + RenderSettings.defaultReflectionMode + "/" + RenderSettings.reflectionIntensity + + " sun=" + (RenderSettings.sun ? RenderSettings.sun.name : "없음"); + } + static string F(Color c) { return "(" + c.r.ToString("F3") + "," + c.g.ToString("F3") + "," + c.b.ToString("F3") + ")"; } + + public static string Shot(Camera cam, string path) + { + if (cam == null) return "카메라 없음"; + System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(path)); + var rt = new RenderTexture(W, H, 24, RenderTextureFormat.ARGB32, RenderTextureReadWrite.sRGB); + rt.antiAliasing = 1; rt.Create(); + var pT = cam.targetTexture; var pA = RenderTexture.active; + cam.targetTexture = rt; cam.Render(); RenderTexture.active = rt; + var tex = new Texture2D(W, H, TextureFormat.RGB24, false); + tex.ReadPixels(new Rect(0, 0, W, H), 0, 0); tex.Apply(); + RenderTexture.active = pA; cam.targetTexture = pT; + System.IO.File.WriteAllBytes(path, tex.EncodeToPNG()); + var px = tex.GetPixels32(); long r = 0, g = 0, b = 0; + for (int i = 0; i < px.Length; i += 7) { r += px[i].r; g += px[i].g; b += px[i].b; } + int n = (px.Length + 6) / 7; + string s = "#" + ((int)(r / n)).ToString("X2") + ((int)(g / n)).ToString("X2") + ((int)(b / n)).ToString("X2"); + Object.DestroyImmediate(tex); rt.Release(); Object.DestroyImmediate(rt); + return s + " → " + path; + } +} + +public class WL816h_RollbackRunner : MonoBehaviour +{ + void Start() { StartCoroutine(Co()); } + + IEnumerator Co() + { + var sb = new System.Text.StringBuilder(); + var cfg = WL.Look.Farm.WLIslandLookSettings.Instance; + string tag = "enabled_=" + (cfg == null ? -1 : cfg.enabled_) + + " skyScope=" + (cfg == null ? -1 : cfg.skyScopeEnabled) + + " waterMode=" + (cfg == null ? -1 : cfg.waterMode); + sb.AppendLine("=== 되돌리기 실측 [" + tag + "] ==="); + string pristine = RB.Sky(); + sb.AppendLine("InGame 원래 하늘 : " + pristine); + + var op = SceneManager.LoadSceneAsync("Level01", LoadSceneMode.Additive); + while (op != null && !op.isDone) yield return null; + for (int i = 0; i < 7; i++) yield return new WaitForSeconds(1f); + + Renderer water = null; + foreach (var r in Object.FindObjectsByType(FindObjectsInactive.Exclude, FindObjectsSortMode.None)) + if (r != null && r.gameObject.scene.name == "Level01" && r.name == "Water") water = r; + sb.AppendLine("물 : " + (water == null ? "없음" : water.sharedMaterial.name + " / " + water.sharedMaterial.shader.name)); + sb.AppendLine("머티리얼 교체 : 렌더러 " + WL.Look.Farm.WLIslandLook.SwappedRenderers + + " · 물 " + WL.Look.Farm.WLIslandLook.WaterSwapped); + sb.AppendLine("풀 : " + WL.Look.Farm.WLIslandGrass.LastLog); + sb.AppendLine("RefLook : " + WL.Look.Arena.WLReferenceLook.IsApplied); + sb.AppendLine("SkyScope : held=" + WL.Look.Farm.WLSkyScope.Held + + " acquires=" + WL.Look.Farm.WLSkyScope.Acquires + " restores=" + WL.Look.Farm.WLSkyScope.Restores); + sb.AppendLine("섬 하늘 : " + RB.Sky()); + + Camera live = null; + foreach (var c in Object.FindObjectsByType(FindObjectsInactive.Exclude, FindObjectsSortMode.None)) + { + if (!c.gameObject.activeInHierarchy || !c.enabled || c.targetTexture != null) continue; + if (c.name.StartsWith("~WL816h")) continue; + if (live == null || c.depth > live.depth) live = c; + } + string shot = "Screenshots_WL/WL816h/z_rollback_" + (cfg != null && cfg.enabled_ == 0 ? "off" : "water_now") + ".png"; + sb.AppendLine("화면 : " + RB.Shot(live, shot)); + + // 섬을 내리고 전투 맵 → 하늘이 원래대로인가 + var u = SceneManager.UnloadSceneAsync("Level01"); + while (u != null && !u.isDone) yield return null; + yield return new WaitForSeconds(2.5f); + var b = SceneManager.LoadSceneAsync("Map_C01", LoadSceneMode.Additive); + while (b != null && !b.isDone) yield return null; + yield return new WaitForSeconds(1.5f); + string after = RB.Sky(); + sb.AppendLine("전투 맵 : " + after); + sb.AppendLine("🔴 원래대로 = " + (after == pristine ? "예" : "🔴 아니오 (전 " + pristine + ")")); + + string path = "AgentScripts/WL816h_ROLLBACK_" + (cfg != null && cfg.enabled_ == 0 ? "R2" : "R1") + ".txt"; + System.IO.File.WriteAllText(path, sb.ToString()); + Debug.Log("[816h rollback]\n" + sb); + } +} diff --git a/AgentScripts/WL816h_VERIFY.txt b/AgentScripts/WL816h_VERIFY.txt new file mode 100644 index 000000000..408896a2e --- /dev/null +++ b/AgentScripts/WL816h_VERIFY.txt @@ -0,0 +1,51 @@ +=== WL-816h 적용 확인 (PD 경로 = InGame 활성 + Level01 Additive) === +0) InGame 원래 하늘 : amb=Skybox light=(0.212,0.227,0.259) skySrc=(0.212,0.227,0.259) I=1 skybox=Default-Skybox fog=False refl=Skybox/1 sun=없음 + Load_Map(900) = 🔴 로그인 없이는 못 탄다 → LoadSceneAsync(Level01, Additive) 로 대체(816f 와 같음) + +1) 섬 진입 — 활성씬=InGame sceneCount=2 + IslandLook 렌더러 1575 · 물 교체 1 · refLook=True + 🔴 SkyScope held=True by=Level01 acquires=1 restores=0 + 섬 하늘 = amb=Flat light=(0.217,0.228,0.250) skySrc=(0.217,0.228,0.250) I=1 skybox=Default-Skybox fog=False refl=Skybox/1 sun=DirectionalLight + 물 렌더러 = Water mat=Farm_Water_WL_C shader=Shader Graphs/ToonWaterU queue=3000 + 보이는 카메라 = MainCamera(Level01) + +2) 물 값 3단 비교 + 성능 (같은 카메라 1080×1920 · 60프레임 오프스크린) + [지금(FI SimpleWater)] 0.828 ms/frame + 게임화면 상10%=#5BB5FE 중=#8BC1AA 하10%=#5BB5FE → Screenshots_WL/WL816h/w_0_now_live.png + 수평선 상10%=#6174C2 중=#5CB7FE 하10%=#8AB1CC → Screenshots_WL/WL816h/w_0_now_horizon.png + [A=WL_Water_Ocean 원본] 0.864 ms/frame + 게임화면 상10%=#0FBFEB 중=#77C2A6 하10%=#1DC0E9 → Screenshots_WL/WL816h/w_1_a_live.png + 수평선 상10%=#6174C2 중=#2BC2EF 하10%=#4497B6 → Screenshots_WL/WL816h/w_1_a_horizon.png + [B=데모 톤] 0.814 ms/frame + 게임화면 상10%=#50B0EB 중=#83BEA6 하10%=#53B0E9 → Screenshots_WL/WL816h/w_2_b_live.png + 수평선 상10%=#6174C2 중=#55B1EF 하10%=#76A0B9 → Screenshots_WL/WL816h/w_2_b_horizon.png + [C=차분] 0.853 ms/frame + 게임화면 상10%=#6097C2 중=#88B89B 하10%=#6397C1 → Screenshots_WL/WL816h/w_3_c_live.png + 수평선 상10%=#6174C2 중=#659AC5 하10%=#8093A3 → Screenshots_WL/WL816h/w_3_c_horizon.png + → 채택 = Farm_Water_WL_C + +2-b) 성능 전/후 (같은 카메라 · 60프레임 × 2회 · 순서 교대) + 0회차 전(FI SimpleWater) = 0.855 ms/frame + 0회차 후(Farm_Water_WL_C) = 0.901 ms/frame + 1회차 전(FI SimpleWater) = 0.889 ms/frame + 1회차 후(Farm_Water_WL_C) = 0.886 ms/frame + 3단 비교 한 장 = Screenshots_WL/WL816h/e_water_steps.png · e_water_steps_horizon.png + +3) 적용 후 + 섬 게임화면 = 상10%=#6097C2 중=#87B79B 하10%=#6397C1 → Screenshots_WL/WL816h/b_after_island.png + 수평선 = 상10%=#6174C2 중=#659AC5 하10%=#8093A4 → Screenshots_WL/WL816h/b_after_horizon.png + 물 근접 = 상10%=#8399E6 중=#78807A 하10%=#4C7EA7 → Screenshots_WL/WL816h/b_after_water.png + 하늘만 = 상10%=#4958A3 중=#7186D3 하10%=#6598C2 → Screenshots_WL/WL816h/b_after_sky.png + 좌우 비교 = Screenshots_WL/WL816h/c_side_by_side.png (좌 지금 / 우 적용 후) + +4) 🔴 맵별 하늘 격리 — 섬 → 던전 → 전투 맵 + [섬] amb=Flat light=(0.217,0.228,0.250) skySrc=(0.217,0.228,0.250) I=1 skybox=Default-Skybox fog=False refl=Skybox/1 sun=DirectionalLight + [섬] 하늘 = 상10%=#4958A3 중=#7186D3 하10%=#6598C2 → Screenshots_WL/WL816h/f1_island_sky.png + [던전] SkyScope held=True by=Level01 acquires=1 restores=0 + [던전] amb=Flat light=(0.217,0.228,0.250) skySrc=(0.217,0.228,0.250) I=1 skybox=Default-Skybox fog=False refl=Skybox/1 sun=Directional Light + [던전] 하늘 = 상10%=#4958A3 중=#7186D3 하10%=#60506F → Screenshots_WL/WL816h/f2_dungeon_sky.png + [전투] SkyScope held=False acquires=1 restores=1 + [전투] amb=Skybox light=(0.212,0.227,0.259) skySrc=(0.212,0.227,0.259) I=1 skybox=Default-Skybox fog=False refl=Skybox/1 sun=없음 + [전투] 하늘 = 상10%=#586773 중=#839397 하10%=#4D3A1D → Screenshots_WL/WL816h/f3_battle_sky.png + 🔴 원래대로인가 = 예 — 글자 하나까지 같다(오염 0) + 한 장 = Screenshots_WL/WL816h/f_sky_isolation.png (좌 섬 / 중 던전 / 우 전투 맵) diff --git a/AgentScripts/WL816h_Verify.cs b/AgentScripts/WL816h_Verify.cs index f4a4444c0..64bb47e70 100644 --- a/AgentScripts/WL816h_Verify.cs +++ b/AgentScripts/WL816h_Verify.cs @@ -247,6 +247,23 @@ public class WL816h_VerifyRunner : MonoBehaviour yield return null; L(" → 채택 = " + (cfg != null && cfg.waterTo != null ? cfg.waterTo.name : "?")); + // ── 2-b) 성능 전/후 — 순서 바꿔 두 번씩 (측정 순서 편향 제거) ── + L(""); + L("2-b) 성능 전/후 (같은 카메라 · 60프레임 × 2회 · 순서 교대)"); + var adopted = cfg != null ? cfg.waterTo : null; + for (int round = 0; round < 2; round++) + { + foreach (var pair in new[] { new object[] { "전(FI SimpleWater)", now }, new object[] { "후(" + (adopted ? adopted.name : "?") + ")", adopted } }) + { + var m = pair[1] as Material; if (m == null) continue; + if (water != null) water.sharedMaterial = m; + yield return null; yield return null; + L(" " + round + "회차 " + (string)pair[0] + " = " + WL816h_Verify.Ms(live, 60).ToString("F3") + " ms/frame"); + } + } + if (water != null && adopted != null) water.sharedMaterial = adopted; + yield return null; + WL816h_Verify.Strip(liveShots, WL816h_Verify.Dir + "e_water_steps.png"); WL816h_Verify.Strip(horizonShots, WL816h_Verify.Dir + "e_water_steps_horizon.png"); L(" 3단 비교 한 장 = " + WL816h_Verify.Dir + "e_water_steps.png · e_water_steps_horizon.png"); diff --git a/Assets/WL/Look/Farm/Resources/WL/WLIslandLookSettings.asset b/Assets/WL/Look/Farm/Resources/WL/WLIslandLookSettings.asset index 55f4786a1..ac793f475 100644 --- a/Assets/WL/Look/Farm/Resources/WL/WLIslandLookSettings.asset +++ b/Assets/WL/Look/Farm/Resources/WL/WLIslandLookSettings.asset @@ -61,9 +61,10 @@ MonoBehaviour: - WL_FarmLook - WL_Dungeon01 - WL_Dungeon02 + skyReleaseDelaySeconds: 1.5 waterMode: 1 waterFrom: {fileID: 2100000, guid: ce0f8fd131f36964dbc918b8c63f838b, type: 2} - waterTo: {fileID: 2100000, guid: 4ccbf1a15347b64459d3a1fa63cc303d, type: 2} + waterTo: {fileID: 2100000, guid: c4a590309ecaa044da75b96fa1e150a3, type: 2} grassEnabled: 1 scatter: - enabled_: 1