diff --git a/Assets/WL/Island/Resources/WL/WLIslandSettings.asset b/Assets/WL/Island/Resources/WL/WLIslandSettings.asset index 493872b52..ba30bc8a7 100644 --- a/Assets/WL/Island/Resources/WL/WLIslandSettings.asset +++ b/Assets/WL/Island/Resources/WL/WLIslandSettings.asset @@ -92,7 +92,7 @@ MonoBehaviour: campTentFaceYawOffset: 0 campFireScale: 2.4 campTentScale: 2.4 - campDecorSnapToGround: 1 + campDecorSnapToGround: 0 applyStartCoin: 1 startCoin: 10 saveResetToken: 816zc-1 diff --git a/Assets/WL/Island/WLIslandGateFlow.cs b/Assets/WL/Island/WLIslandGateFlow.cs index 5472479a6..7002077ed 100644 --- a/Assets/WL/Island/WLIslandGateFlow.cs +++ b/Assets/WL/Island/WLIslandGateFlow.cs @@ -91,6 +91,7 @@ namespace WL.Island HideIslandFences(cfg, scene, null); WLIslandTileFenceStrip.Apply(cfg, scene); // 2026-09-15 Lead 실측 — 타일 메시에 구워진 난간 제거 + HookFenceGuard(cfg, scene); // 2026-09-15 — 그리기 직전마다 fence 렌더러 차단 + 정체 기록 // 2026-09-15 PD 「게임 시작 시 섬에 울타리가 여전히 남아 있다」 — 시작 직후 FI 타일 활성화가 렌더러를 다시 켜므로 // farmReHideDelaySeconds 간격으로 3회 더 훑는다(이미 꺼진 것은 건너뛴다 · 값 0 이면 무동작). if (cfg.hideIslandFences != 0 && WLIslandBridge.Runner != null) @@ -457,6 +458,52 @@ namespace WL.Island public static int WorkersHidden; + // ───────────────────────────────────────────────────────────────── + // 2026-09-15 Lead 실측 — 울타리는 오브젝트 숨김·타일 메시 자르기 뒤에도 화면에 남았고, isVisible 목록에도 안 잡혔다. + // 마지막 수단: 카메라가 그리기 **직전**(beginCameraRendering)마다 섬 씬의 렌더러를 훑어 이름 또는 메시 이름에 + // 「fence」 가 들어간 것을 끄고, 무엇을 껐는지 `FenceGuardLog` 에 남긴다(정체 확인용). 씬이 내려가면 해제. + // ───────────────────────────────────────────────────────────────── + public static string FenceGuardLog = ""; + public static int FenceGuardHidden; + static bool s_guardHooked; + static Scene s_guardScene; + static WLIslandSettings s_guardCfg; + + static void HookFenceGuard(WLIslandSettings cfg, Scene scene) + { + s_guardCfg = cfg; s_guardScene = scene; + if (s_guardHooked) return; + UnityEngine.Rendering.RenderPipelineManager.beginCameraRendering += OnBeginCameraFenceGuard; + s_guardHooked = true; + } + + static void OnBeginCameraFenceGuard(UnityEngine.Rendering.ScriptableRenderContext ctx, Camera cam) + { + if (s_guardCfg == null || s_guardCfg.hideIslandFences == 0) return; + if (!s_guardScene.IsValid() || !s_guardScene.isLoaded) + { + UnityEngine.Rendering.RenderPipelineManager.beginCameraRendering -= OnBeginCameraFenceGuard; + s_guardHooked = false; + return; + } + var rends = Object.FindObjectsByType(FindObjectsInactive.Exclude, FindObjectsSortMode.None); + for (int i = 0; i < rends.Length; i++) + { + var r = rends[i]; + if (r == null || !r.enabled) continue; + bool hit = r.gameObject.name.IndexOf("fence", System.StringComparison.OrdinalIgnoreCase) >= 0; + if (!hit) + { + var mf = r.GetComponent(); + if (mf != null && mf.sharedMesh != null && mf.sharedMesh.name.IndexOf("fence", System.StringComparison.OrdinalIgnoreCase) >= 0) hit = true; + } + if (!hit) continue; + r.enabled = false; FenceGuardHidden++; + var t = r.transform; string path = t.name; while (t.parent != null) { t = t.parent; path = t.name + "/" + path; } + if (FenceGuardLog.Length < 1200) FenceGuardLog += " | " + path + " @" + r.transform.position.ToString("F1") + " scn=" + r.gameObject.scene.name; + } + } + static IEnumerator Co_HideWorkers(Scene scene) { float t = 0f;