[WL-814c] 스왑 캐시 버그 2건 수정 · ApplyNow 왕복 프로브 추가 (#814)

- ResetForProbe 가 「스왑할 것 없음」 캐시를 안 비워 다음 ApplyNow 가 전부 건너뛰던 문제
- 물 스왑을 맵 스윕보다 먼저 — 맵 스윕이 물 렌더러를 캐시에 넣어 물이 안 바뀌던 문제
- 프로브 H(ApplyNow/RestoreNow 왕복) 추가 → RESULT PASS 46/46

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
깃 관리자 2026-09-11 00:11:11 +09:00
parent addef288ea
commit c365c2e9f4
4 changed files with 60 additions and 8 deletions

View File

@ -1,4 +1,4 @@
WL-814c 룩 캡처(직교 픽셀 카메라 근사 270×480 → 1080×1920) · 2026-09-11 00:03:31
WL-814c 룩 캡처(직교 픽셀 카메라 근사 270×480 → 1080×1920) · 2026-09-11 00:10:38
PASS E0 맵 — WL_Nature
기준점(나무·수풀 군락 44그루/25 m · 물까지 3 m) (41.2, 0.0, 85.2) → PC (52.2, 0.1, 84.7)
카메라 직교 size 3.8 · pos (74.8, 13.0, 83.7) · look (50.2, 1.2, 84.8) · 811o(h 76 · yaw 233) · near 0.1 / far 120 → 깊이 임계 0.004 = 단차 0.48 m
@ -7,10 +7,10 @@ WL-814c 룩 캡처(직교 픽셀 카메라 근사 270×480 → 1080×1920) · 20
PASS E look_1_original.png — ⓐ 원본(URP/Lit) · 104391 B · 색 392종 · 진한픽셀 0 · drawCalls 0 · batches 0 · tri 0
PASS E look_2_toon_outline.png — ⓑ Toon 램프 + 1px 픽셀 외곽선(맵 1268 렌더러 · 구름 off) · 72352 B · 색 296종 · 진한픽셀 0 · drawCalls 0 · batches 0 · tri 0
잔디 드로우 구성 8개(지면×{잔디,꽃}) · bounds (300, 14, 400)
PASS E look_3_grass.png — ⓒ + 인스턴싱 잔디(지면 4 · 인스턴스 8175) · 81033 B · 색 308종 · 진한픽셀 0 · drawCalls 0 · batches 0 · tri 0
PASS E look_4_clouds.png — ⓓ + 구름 그림자 · 86347 B · 색 329종 · 진한픽셀 0 · drawCalls 0 · batches 0 · tri 0
PASS E look_5_char_before.png — ⓔ 캐릭터 원본(MK/Toon) · 배경만 Critter Toon · 84134 B · 색 597종 · 진한픽셀 4 · drawCalls 0 · batches 0 · tri 0
PASS E look_6_char_after.png — ⓕ 캐릭터 Critter Toon(PC 11 · 몹 3 렌더러) · 79863 B · 색 544종 · 진한픽셀 1 · drawCalls 0 · batches 0 · tri 0
PASS E look_3_grass.png — ⓒ + 인스턴싱 잔디(지면 4 · 인스턴스 8175) · 79740 B · 색 306종 · 진한픽셀 0 · drawCalls 0 · batches 0 · tri 0
PASS E look_4_clouds.png — ⓓ + 구름 그림자 · 84588 B · 색 338종 · 진한픽셀 0 · drawCalls 0 · batches 0 · tri 0
PASS E look_5_char_before.png — ⓔ 캐릭터 원본(MK/Toon) · 배경만 Critter Toon · 85445 B · 색 597종 · 진한픽셀 4 · drawCalls 0 · batches 0 · tri 0
PASS E look_6_char_after.png — ⓕ 캐릭터 Critter Toon(PC 11 · 몹 3 렌더러) · 80890 B · 색 551종 · 진한픽셀 1 · drawCalls 0 · batches 0 · tri 0
PASS E9 캡처 6장 — 6장
RESULT PASS · 10/10 · FAIL 0

View File

@ -1,4 +1,4 @@
WL-814c 프로브 · 2026-09-11 00:04:03 · Unity 6000.3.23f1
WL-814c 프로브 · 2026-09-11 00:10:24 · Unity 6000.3.23f1
## A. 설정 SO · 스왑 표
PASS A1 SO 로드 — Assets/WL/Look/Env/Resources/WL/WLEnvLookSettings.asset
@ -61,4 +61,14 @@ WL-814c 프로브 · 2026-09-11 00:04:03 · Unity 6000.3.23f1
PASS G4 enabled=0 → 피처 off — isActive=False
PASS G5 에디트 모드 러너 오브젝트 0 — 0개
RESULT PASS · 38/38 · FAIL 0
## H. ApplyNow / RestoreNow 왕복 (게임이 실제로 부르는 진입점)
PASS H1 ApplyNow — 렌더러 1268 · 슬롯 1268 · 물 5 · 잔디 4(8175개 · +8 드로우콜)
PASS H2 피처 활성 — isActive=True
PASS H3 잔디 컴포넌트 — 4개
PASS H4 이중 적용 무해 — 두 번째 ApplyNow = 무동작
PASS H5 원복 == 원본 — 불일치 0 / 렌더러 1299
PASS H6 피처 원복 — isActive=False
PASS H7 잔디 파괴 — 0개
PASS H8 에셋 dirty 0 — renderer dirty=False
RESULT PASS · 46/46 · FAIL 0

View File

@ -53,6 +53,7 @@ public static class WL814c_Probe
E_Water(map);
F_Gc();
G_C8(map);
H_ApplyNow(map);
}
catch (Exception ex) { s_fail++; L("EXCEPTION " + ex); }
finally
@ -318,6 +319,43 @@ public static class WL814c_Probe
WLEnvLookSettings.RuntimeDisabled = false;
}
// ── H. 실제 진입점(ApplyNow) 왕복 ───────────────────────────────────────
// 🔴 InGameInfo.Ins 는 자동 생성되지 않는 순수 static 필드라(실측) 에디트 모드에서 null 이고,
// MyValue.MyPC 도 null 이라 ApplyNow 는 맵·물·잔디·피처 경로만 타고 캐릭터 경로는 건너뛴다.
static void H_ApplyNow(GameObject map)
{
L("");
L("## H. ApplyNow / RestoreNow 왕복 (게임이 실제로 부르는 진입점)");
if (map == null) return;
var before = Snapshot(map);
EnvLook.ResetForProbe();
bool ok = EnvLook.ApplyNow("probe-h");
var rd = AssetDatabase.LoadAssetAtPath<ScriptableRendererData>(kRendererPath);
bool feature = false;
foreach (var f in rd.rendererFeatures) if (f is global::Environment.PixelOutlineSetupFeature) feature = f.isActive;
int grass = map.GetComponentsInChildren<global::Environment.Instancing.MeshInstancesBehaviour>(true).Length;
Chk("H1 ApplyNow", ok && EnvLook.SwappedRenderers > 0 && EnvLook.WaterSwapped > 0 && EnvLook.GrassObjects > 0,
"렌더러 " + EnvLook.SwappedRenderers + " · 슬롯 " + EnvLook.SwappedSlots +
" · 물 " + EnvLook.WaterSwapped + " · 잔디 " + EnvLook.GrassObjects + "(" + EnvLook.GrassInstances + "개 · +" + EnvLook.GrassDrawCalls + " 드로우콜)");
Chk("H2 피처 활성", feature, "isActive=" + feature);
Chk("H3 잔디 컴포넌트", grass == EnvLook.GrassObjects && grass > 0, grass + "개");
Chk("H4 이중 적용 무해", EnvLook.ApplyNow("probe-h2") == false, "두 번째 ApplyNow = 무동작");
EnvLook.RestoreNow("probe-h");
var back = Snapshot(map);
int mismatch = 0;
foreach (var kv in before) { string now; if (back.TryGetValue(kv.Key, out now) && now != kv.Value) mismatch++; }
bool feature2 = false;
foreach (var f in rd.rendererFeatures) if (f is global::Environment.PixelOutlineSetupFeature) feature2 = f.isActive;
int grass2 = map.GetComponentsInChildren<global::Environment.Instancing.MeshInstancesBehaviour>(true).Length;
Chk("H5 원복 == 원본", mismatch == 0, "불일치 " + mismatch + " / 렌더러 " + before.Count);
Chk("H6 피처 원복", !feature2, "isActive=" + feature2);
Chk("H7 잔디 파괴", grass2 == 0, grass2 + "개");
Chk("H8 에셋 dirty 0", !EditorUtility.IsDirty(rd), "renderer dirty=" + EditorUtility.IsDirty(rd));
}
// ═════════════════════════════════════════════════════════════════════════
// Capture — 임시 씬(저장 0) · 직교 · 270×480 렌더 → 1080×1920 확대 · 6장
// ═════════════════════════════════════════════════════════════════════════

View File

@ -129,9 +129,10 @@ namespace WL.Look.Env
Transform mapRoot = FindMapRoot();
// 🔴 물이 먼저다 — 맵 스윕이 「스왑할 것 없음」으로 표시한 렌더러는 다시 보지 않기 때문.
if (c.waterEnabled) SwapWater(mapRoot, c);
if (c.swapMap && mapRoot != null) SweepRoot(mapRoot);
if (c.swapCharacters) SweepCharacters();
if (c.waterEnabled) SwapWater(mapRoot, c);
if (c.outlineFeature) SetFeature(true);
if (c.grassEnabled) AttachGrass(mapRoot, c);
@ -178,6 +179,9 @@ namespace WL.Look.Env
public static void ResetForProbe()
{
RestoreNow("probe-reset");
// 🔴 RestoreNow 는 「적용 중이 아니면」 곧장 돌아가므로 캐시를 여기서 무조건 비운다.
// (안 비우면 이전에 훑어 「스왑할 것 없음」으로 표시된 렌더러가 영영 건너뛰어진다)
s_seenRenderers.Clear(); s_seenSpawns.Clear(); s_recs.Clear();
s_lastPc = null; s_lastMapId = int.MinValue; s_nextPoll = 0f; s_nextSpawnSweep = 0f; s_faulted = false;
s_tableBuilt = false; s_table.Clear();
Boundaries = Applies = Restores = SkippedLobby = 0;