[WL-815d2] 메뉴 숨김이 싱글턴 Awake 를 막던 버그: activeInHierarchy 로 판정 · 비활성 가지는 미루고 ReassertHide 가 처리 (#815)

몹 처치마다 MobActor.Set_Die()(MobActor.cs:444)에서 NullReferenceException 이 났다.
원인 = 프리팹 저장 상태가 비활성인 IngameUIs 가지 아래의 MonsterSimpleInfo 를
스테이지 진입 때 SetActive(false) 해 버려서, 가지가 켜져도 그 노드만 꺼진 채 남아
Awake 가 영영 안 돌고 MonoBehaviourSingletonTemplate.Ins 가 null 로 남은 것.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
깃 관리자 2026-09-11 09:35:07 +09:00
parent eec40635ee
commit 9db9abce35
1 changed files with 17 additions and 2 deletions

View File

@ -55,6 +55,8 @@ namespace WL.UI
// ── 진단(프로브가 읽는다 · 실측만) ────────────────────────────────────
public static int EnteredSeen, CountdownSeen, StartedSeen, EnemySeen, TimeSeen, ClearedSeen, FailedSeen, ExitedSeen;
public static int MenuHideCalls, MenuRestoreCalls, MenuMissing;
/// <summary>가지가 비활성이라 숨김을 미룬 노드 수(WL-815d2 · ReassertHide 가 뒤늦게 끈다).</summary>
public static int MenuDeferred;
public static int MenuReassertCalls, MenuReassertHits; // 원본이 다시 켠 것을 도로 끈 횟수
public static int RetryCalls, NextCalls, LobbyCalls, RestartCalls;
public static string LastLog = "";
@ -303,7 +305,11 @@ namespace WL.UI
{
var t = s_hidden[i];
if (t == null) continue;
if (t.gameObject.activeSelf) { t.gameObject.SetActive(false); n++; MenuReassertHits++; }
// 🔴 activeSelf 가 아니라 activeInHierarchy 로 판정한다(WL-815d2).
// 부모 가지가 아직 꺼져 있는 노드를 끄면 그 노드의 Awake 가 영영 안 돌아
// 싱글턴(MonoBehaviourSingletonTemplate.Ins)이 null 로 남는다.
// 여기서 미루면 가지가 켜지는 순간 Awake 가 돌고, 그 다음 틱에 끈다.
if (t.gameObject.activeInHierarchy) { t.gameObject.SetActive(false); n++; MenuReassertHits++; }
}
if (n > 0) MenuReassertCalls++;
return n;
@ -409,6 +415,7 @@ namespace WL.UI
s_hiddenCount = 0;
MenuMissing = 0;
int hidden = 0;
int deferred = 0; // 가지가 아직 꺼져 있어 미룬 것(WL-815d2)
for (int i = 0; i < paths.Length; i++)
{
if (string.IsNullOrEmpty(paths[i])) continue;
@ -417,10 +424,18 @@ namespace WL.UI
s_hidden[s_hiddenCount] = t;
s_hiddenPrev[s_hiddenCount] = t.gameObject.activeSelf;
s_hiddenCount++;
if (t.gameObject.activeSelf) { t.gameObject.SetActive(false); hidden++; }
// 🔴 WL-815d2 — 켜져 있는 가지의 노드만 끈다(위 ReassertHide 주석 참조).
// 실측: `IngameUIs` 는 프리팹 저장 상태가 비활성이라, 그 아래
// `MonsterSimpleInfo`(싱글턴)를 여기서 끄면 Awake 가 안 돌고 `Ins` 가 null 로 남아
// 몹 처치마다 `MobActor.Set_Die()`(MobActor.cs:444)에서 NRE 가 났다.
// 못 끈 것은 `ReassertHide()` 가 가지 활성 뒤에 끈다(= 화면에는 그대로 안 보인다).
if (t.gameObject.activeInHierarchy) { t.gameObject.SetActive(false); hidden++; }
else deferred++;
}
MenuHideCalls++;
MenuDeferred = deferred;
return "메뉴 숨김 — 경로 " + paths.Length + "개 중 찾음 " + s_hiddenCount + " · 실제로 끈 것 " + hidden +
" · 미룸(가지 비활성) " + deferred +
" · 못 찾음 " + MenuMissing + (MenuMissing > 0 ? "(마지막 \"" + LastMissingPath + "\")" : "");
}