348 lines
20 KiB
C#
348 lines
20 KiB
C#
|
|
// WL-814e 프로브 — EnvLook(814c) ↔ LookModeHub(814d) 브리지 + 프리셋 값 정정 실측
|
|||
|
|
// unity command run_script --file AgentScripts/WL814e_Probe.cs --entry WL814e_Probe.RunAll --project-path E:\NerdNavis\WL_wt\ui
|
|||
|
|
// 산출물: <worktree>/AgentScripts/WL814e_PROBE.txt
|
|||
|
|
// 🔴 에디트 모드 전용 · Play 0 · 로그인 0 · 임시 씬(NewScene) 저장 0 · AssetDatabase.SaveAssets 0 · 에셋 파일 쓰기 0.
|
|||
|
|
// 🔴 SO 필드를 잠시 바꾸는 구간은 전부 try/finally 로 원값 복구(SetDirty 0 이라 디스크에 안 쓰인다).
|
|||
|
|
// 🔴 Critter 의 전역 네임스페이스 `Environment` 는 System.Environment 와 충돌 → global:: 로 명시.
|
|||
|
|
|
|||
|
|
using System;
|
|||
|
|
using System.Collections.Generic;
|
|||
|
|
using System.IO;
|
|||
|
|
using System.Text;
|
|||
|
|
using UnityEditor;
|
|||
|
|
using UnityEditor.SceneManagement;
|
|||
|
|
using UnityEngine;
|
|||
|
|
using UnityEngine.Profiling;
|
|||
|
|
using UnityEngine.SceneManagement;
|
|||
|
|
using WL.Look.Env;
|
|||
|
|
using WL.Look.Toggle;
|
|||
|
|
|
|||
|
|
public static class WL814e_Probe
|
|||
|
|
{
|
|||
|
|
const string kTxt = "AgentScripts/WL814e_PROBE.txt";
|
|||
|
|
const string kMapPrefab = "Assets/Res_Addr/Map/WL_Nature.prefab";
|
|||
|
|
|
|||
|
|
static StringBuilder s_sb;
|
|||
|
|
static int s_pass, s_fail;
|
|||
|
|
static void L(string s) { s_sb.AppendLine(s); }
|
|||
|
|
static void Chk(string n, bool ok, string d) { if (ok) s_pass++; else s_fail++; L((ok ? " PASS " : " FAIL ") + n + " — " + d); }
|
|||
|
|
|
|||
|
|
// 표(발주서 WL-814e §1-2) — 모드별 h / d / up / ortho / px / envLookOn / 표기
|
|||
|
|
static readonly float[] kH = { 76f, 76f, 76f, 76f };
|
|||
|
|
static readonly float[] kD = { 3f, 3f, 3f, 3f };
|
|||
|
|
static readonly float[] kUp = { 2.4f, 2.4f, 2.4f, 2.4f };
|
|||
|
|
static readonly float[] kOrtho = { 0f, 3.4f, 4.6f, 4.6f }; // 0번은 리그 해제 = 미사용
|
|||
|
|
static readonly int[] kPx = { 0, 480, 480, 360 };
|
|||
|
|
static readonly bool[] kEnv = { false, true, true, true };
|
|||
|
|
static readonly string[] kName = { "기본", "도트A", "도트B(넓게)", "도트C(굵게)" };
|
|||
|
|
|
|||
|
|
public static void RunAll()
|
|||
|
|
{
|
|||
|
|
s_sb = new StringBuilder(); s_pass = 0; s_fail = 0;
|
|||
|
|
L("WL-814e 프로브 · " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " · Unity " + Application.unityVersion);
|
|||
|
|
L("playMode=" + Application.isPlaying);
|
|||
|
|
|
|||
|
|
var cfg = WLEnvLookSettings.Instance;
|
|||
|
|
bool savedFollow = cfg != null && cfg.followLookModeHub;
|
|||
|
|
bool savedRtE = WLEnvLookSettings.RuntimeDisabled;
|
|||
|
|
bool savedRtL = WLLookModeSettings.RuntimeDisabled;
|
|||
|
|
Scene temp = default(Scene);
|
|||
|
|
GameObject map = null;
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
A_Values();
|
|||
|
|
temp = EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects, NewSceneMode.Single);
|
|||
|
|
map = Inst(kMapPrefab);
|
|||
|
|
L("");
|
|||
|
|
L("임시 씬 '" + temp.name + "' · 맵 " + (map != null ? map.name : "(없음)") +
|
|||
|
|
" · 렌더러 " + (map != null ? map.GetComponentsInChildren<Renderer>(true).Length : 0) + "개");
|
|||
|
|
|
|||
|
|
B_GateOff(map);
|
|||
|
|
C_HubEvent(map);
|
|||
|
|
D_FollowOff(map);
|
|||
|
|
E_Unhook(map);
|
|||
|
|
F_Gc();
|
|||
|
|
G_C8(map);
|
|||
|
|
}
|
|||
|
|
catch (Exception ex) { s_fail++; L("EXCEPTION " + ex); }
|
|||
|
|
finally
|
|||
|
|
{
|
|||
|
|
try { EnvLook.UnhookHub(); EnvLook.RestoreNow("probe-final"); EnvLook.ResetForProbe(); } catch { }
|
|||
|
|
try { LookModeHub.SetEnvLook(false); LookModeHub.ResetAll(); } catch { }
|
|||
|
|
WLEnvLookSettings.RuntimeDisabled = savedRtE;
|
|||
|
|
WLLookModeSettings.RuntimeDisabled = savedRtL;
|
|||
|
|
if (cfg != null) cfg.followLookModeHub = savedFollow; // 🔴 원값 복구(SetDirty 0)
|
|||
|
|
if (map != null) UnityEngine.Object.DestroyImmediate(map);
|
|||
|
|
// 🔴 뒤에 도는 프로브(814d)가 Camera.main 을 뺏기지 않도록 빈 씬으로 정리한다(저장 0).
|
|||
|
|
if (temp.IsValid()) temp = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single);
|
|||
|
|
L("");
|
|||
|
|
L("SO 원값 복구 — followLookModeHub=" + (cfg != null ? cfg.followLookModeHub.ToString() : "?") +
|
|||
|
|
" · enabled=" + (cfg != null ? cfg.enabled.ToString() : "?") +
|
|||
|
|
" · RuntimeDisabled(Env/Look)=" + WLEnvLookSettings.RuntimeDisabled + "/" + WLLookModeSettings.RuntimeDisabled);
|
|||
|
|
L("씬 dirty=" + (temp.IsValid() ? temp.isDirty.ToString() : "(무효)") + " · 씬 저장 0 · SaveAssets 0");
|
|||
|
|
L("");
|
|||
|
|
L("RESULT " + (s_fail == 0 ? "PASS" : "FAIL") + " " + s_pass + "/" + (s_pass + s_fail));
|
|||
|
|
var p = Path.Combine(Directory.GetParent(Application.dataPath).FullName, kTxt);
|
|||
|
|
File.WriteAllText(p, s_sb.ToString(), new UTF8Encoding(false));
|
|||
|
|
Debug.Log("[WL814e] → " + p + " · " + (s_fail == 0 ? "PASS" : "FAIL") + " " + s_pass + "/" + (s_pass + s_fail));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// ── A. 값 표 (ⓔ 앞부분) ──────────────────────────────────────────────────
|
|||
|
|
static void A_Values()
|
|||
|
|
{
|
|||
|
|
L("");
|
|||
|
|
L("## A. SO 값 (WLLookModeSettings.asset · WLEnvLookSettings.asset · 전부 실측)");
|
|||
|
|
var s = WLLookModeSettings.Instance;
|
|||
|
|
var c = WLEnvLookSettings.Instance;
|
|||
|
|
if (!Chk2("A0 두 SO 로드", s != null && c != null, "look=" + (s != null) + " env=" + (c != null))) return;
|
|||
|
|
|
|||
|
|
L(" | 모드 | 표기 | 리그 | SO구도 | h | d | up | ortho | px | envLookOn |");
|
|||
|
|
for (int i = 0; i < 4; i++)
|
|||
|
|
{
|
|||
|
|
var p = s.Preset(i);
|
|||
|
|
L(" | " + i + " | " + p.name + " | " + (p.pixelRig ? "직교" : "원근") + " | " + (p.useSoFraming ? "SO" : "프리셋") +
|
|||
|
|
" | " + p.cameraHeight + " | " + p.distance + " | " + p.distanceUp +
|
|||
|
|
" | " + p.orthoSize + " | " + p.pixelHeight + " | " + (p.envLookOn ? "1" : "0") + " |");
|
|||
|
|
}
|
|||
|
|
Chk("A1 프리셋 4개", s.ModeCount == 4, "ModeCount=" + s.ModeCount);
|
|||
|
|
for (int i = 0; i < 4; i++)
|
|||
|
|
{
|
|||
|
|
var p = s.Preset(i);
|
|||
|
|
bool ok = p.name == kName[i]
|
|||
|
|
&& Mathf.Abs(p.cameraHeight - kH[i]) < 0.001f
|
|||
|
|
&& Mathf.Abs(p.distance - kD[i]) < 0.001f
|
|||
|
|
&& Mathf.Abs(p.distanceUp - kUp[i]) < 0.001f
|
|||
|
|
&& p.envLookOn == kEnv[i]
|
|||
|
|
&& (i == 0 || (Mathf.Abs(p.orthoSize - kOrtho[i]) < 0.001f && p.pixelHeight == kPx[i]));
|
|||
|
|
Chk("A2." + i + " 모드 " + i + " = 표", ok,
|
|||
|
|
p.name + " · h " + p.cameraHeight + " d " + p.distance + " up " + p.distanceUp +
|
|||
|
|
" ortho " + p.orthoSize + " px " + p.pixelHeight + " env " + (p.envLookOn ? 1 : 0));
|
|||
|
|
}
|
|||
|
|
Chk("A3 0번 = 원근 + 811o SO 구도", !s.Preset(0).pixelRig && s.Preset(0).useSoFraming,
|
|||
|
|
"pixelRig=" + s.Preset(0).pixelRig + " useSoFraming=" + s.Preset(0).useSoFraming);
|
|||
|
|
Chk("A4 1~3번 = 도트(직교 리그)", s.Preset(1).pixelRig && s.Preset(2).pixelRig && s.Preset(3).pixelRig, "3/3");
|
|||
|
|
Chk("A5 각도 4행 동일(76/3/2.4)",
|
|||
|
|
s.Preset(0).cameraHeight == s.Preset(1).cameraHeight && s.Preset(1).cameraHeight == s.Preset(2).cameraHeight &&
|
|||
|
|
s.Preset(2).cameraHeight == s.Preset(3).cameraHeight, "h " + s.Preset(0).cameraHeight + " 전부 동일");
|
|||
|
|
Chk("A6 허브 유지 값", s.envFollowsCameraMode && !s.envLookOnAtStart && s.startMode == 0 && s.showButtons,
|
|||
|
|
"envFollows=" + s.envFollowsCameraMode + " envAtStart=" + s.envLookOnAtStart +
|
|||
|
|
" startMode=" + s.startMode + " showButtons=" + s.showButtons);
|
|||
|
|
Chk("A7 WLEnvLookSettings enabled 1 · followLookModeHub 1 · swapCharacters 0",
|
|||
|
|
c.enabled && c.followLookModeHub && !c.swapCharacters,
|
|||
|
|
"enabled=" + c.enabled + " follow=" + c.followLookModeHub + " swapChars=" + c.swapCharacters +
|
|||
|
|
" · grassDensity=" + c.grassDensity + "(유지)");
|
|||
|
|
Chk("A8 Enabled 게이트 통과", WLEnvLookSettings.Enabled, "Enabled=" + WLEnvLookSettings.Enabled);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// ── B. ⓐ 허브 OFF → 맵 경계 → 적용 0 ─────────────────────────────────────
|
|||
|
|
static void B_GateOff(GameObject map)
|
|||
|
|
{
|
|||
|
|
L("");
|
|||
|
|
L("## B. ⓐ 허브 EnvLookOn=false → 맵 진입 경계 → 적용 0");
|
|||
|
|
if (map == null) return;
|
|||
|
|
EnvLook.UnhookHub();
|
|||
|
|
EnvLook.ResetForProbe();
|
|||
|
|
LookModeHub.SetEnvLook(false);
|
|||
|
|
Chk("B0 허브 OFF · 추종 ON", !LookModeHub.EnvLookOn && EnvLook.FollowHub,
|
|||
|
|
"EnvLookOn=" + LookModeHub.EnvLookOn + " FollowHub=" + EnvLook.FollowHub);
|
|||
|
|
|
|||
|
|
bool applied = EnvLook.MapEnter();
|
|||
|
|
int grass = map.GetComponentsInChildren<global::Environment.Instancing.MeshInstancesBehaviour>(true).Length;
|
|||
|
|
Chk("B1 경계 적용 0", !applied && !EnvLook.IsApplied, "MapEnter=" + applied + " IsApplied=" + EnvLook.IsApplied);
|
|||
|
|
Chk("B2 스왑 0 · 잔디 0", EnvLook.SwappedRenderers == 0 && EnvLook.WaterSwapped == 0 && grass == 0,
|
|||
|
|
"렌더러 " + EnvLook.SwappedRenderers + " · 물 " + EnvLook.WaterSwapped + " · 잔디 " + grass);
|
|||
|
|
Chk("B3 게이트 카운터 +1", EnvLook.HubGated == 1, "HubGated=" + EnvLook.HubGated);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// ── C. ⓑ 허브 ON/OFF 이벤트 → 적용 / 원복 전부 일치 ──────────────────────
|
|||
|
|
static void C_HubEvent(GameObject map)
|
|||
|
|
{
|
|||
|
|
L("");
|
|||
|
|
L("## C. ⓑ LookModeHub.EnvLookChanged 구독 → ON 적용 · OFF 원복");
|
|||
|
|
if (map == null) return;
|
|||
|
|
EnvLook.UnhookHub();
|
|||
|
|
EnvLook.ResetForProbe();
|
|||
|
|
LookModeHub.SetEnvLook(false);
|
|||
|
|
var before = Snapshot(map);
|
|||
|
|
|
|||
|
|
bool hooked = EnvLook.HookHub();
|
|||
|
|
Chk("C1 구독 성공 · 현재 값(OFF) 1회 반영", hooked && EnvLook.HubHooked && EnvLook.HubEvents == 1 && !EnvLook.IsApplied,
|
|||
|
|
"HookHub=" + hooked + " HubHooked=" + EnvLook.HubHooked + " HubEvents=" + EnvLook.HubEvents +
|
|||
|
|
" IsApplied=" + EnvLook.IsApplied);
|
|||
|
|
Chk("C2 중복 구독 0", EnvLook.HookHub() == false && EnvLook.HubEvents == 1, "두 번째 HookHub=false · HubEvents=" + EnvLook.HubEvents);
|
|||
|
|
|
|||
|
|
LookModeHub.SetEnvLook(true);
|
|||
|
|
int grassOn = map.GetComponentsInChildren<global::Environment.Instancing.MeshInstancesBehaviour>(true).Length;
|
|||
|
|
Chk("C3 ON → 적용", EnvLook.IsApplied && EnvLook.SwappedRenderers > 0 && EnvLook.HubEvents == 2,
|
|||
|
|
"렌더러 " + EnvLook.SwappedRenderers + " · 슬롯 " + EnvLook.SwappedSlots + " · 물 " + EnvLook.WaterSwapped +
|
|||
|
|
" · 잔디 " + grassOn + "(" + EnvLook.GrassInstances + "개) · HubEvents=" + EnvLook.HubEvents +
|
|||
|
|
" · LastLog='" + EnvLook.LastLog + "'");
|
|||
|
|
|
|||
|
|
LookModeHub.SetEnvLook(false);
|
|||
|
|
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++; }
|
|||
|
|
int grassOff = map.GetComponentsInChildren<global::Environment.Instancing.MeshInstancesBehaviour>(true).Length;
|
|||
|
|
Chk("C4 OFF → 원복 전부 일치", !EnvLook.IsApplied && mismatch == 0 && grassOff == 0 && EnvLook.HubEvents == 3,
|
|||
|
|
"불일치 " + mismatch + "/" + before.Count + " · 복원 렌더러 " + EnvLook.RestoredRenderers +
|
|||
|
|
" · 잔디 " + grassOff + " · HubEvents=" + EnvLook.HubEvents + " · LastLog='" + EnvLook.LastLog + "'");
|
|||
|
|
Chk("C5 같은 값 재설정 → 이벤트 0", DoubleSet(false) && EnvLook.HubEvents == 3, "HubEvents=" + EnvLook.HubEvents);
|
|||
|
|
}
|
|||
|
|
static bool DoubleSet(bool on) { LookModeHub.SetEnvLook(on); return true; }
|
|||
|
|
|
|||
|
|
// ── D. ⓒ followLookModeHub 0 → 814c 원래 동작 ────────────────────────────
|
|||
|
|
static void D_FollowOff(GameObject map)
|
|||
|
|
{
|
|||
|
|
L("");
|
|||
|
|
L("## D. ⓒ followLookModeHub = 0 → 814c 원래 동작(경계 자동 적용 · 허브 참조 0)");
|
|||
|
|
var c = WLEnvLookSettings.Instance;
|
|||
|
|
if (map == null || c == null) return;
|
|||
|
|
EnvLook.UnhookHub();
|
|||
|
|
EnvLook.ResetForProbe();
|
|||
|
|
LookModeHub.SetEnvLook(false); // 허브는 꺼 둔 채로
|
|||
|
|
bool saved = c.followLookModeHub;
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
c.followLookModeHub = false;
|
|||
|
|
Chk("D0 추종 off", !EnvLook.FollowHub, "FollowHub=" + EnvLook.FollowHub + " · 허브 EnvLookOn=" + LookModeHub.EnvLookOn);
|
|||
|
|
|
|||
|
|
bool applied = EnvLook.MapEnter();
|
|||
|
|
int grass = map.GetComponentsInChildren<global::Environment.Instancing.MeshInstancesBehaviour>(true).Length;
|
|||
|
|
Chk("D1 허브가 꺼져 있어도 경계에서 적용", applied && EnvLook.IsApplied && EnvLook.SwappedRenderers > 0,
|
|||
|
|
"MapEnter=" + applied + " · 렌더러 " + EnvLook.SwappedRenderers + " · 물 " + EnvLook.WaterSwapped +
|
|||
|
|
" · 잔디 " + grass + " · LastLog='" + EnvLook.LastLog + "'");
|
|||
|
|
Chk("D2 게이트 0회", EnvLook.HubGated == 0, "HubGated=" + EnvLook.HubGated);
|
|||
|
|
EnvLook.RestoreNow("probe-d");
|
|||
|
|
Chk("D3 추종 off 면 구독도 0", EnvLook.HookHub() == false && !EnvLook.HubHooked && EnvLook.HubEvents == 0,
|
|||
|
|
"HookHub=false · HubHooked=" + EnvLook.HubHooked + " · HubEvents=" + EnvLook.HubEvents);
|
|||
|
|
}
|
|||
|
|
finally { c.followLookModeHub = saved; }
|
|||
|
|
Chk("D4 추종 원복", EnvLook.FollowHub, "FollowHub=" + EnvLook.FollowHub);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// ── E. ⓓ 구독 해제 뒤 이벤트 → 무동작(누수 0) ────────────────────────────
|
|||
|
|
static void E_Unhook(GameObject map)
|
|||
|
|
{
|
|||
|
|
L("");
|
|||
|
|
L("## E. ⓓ 구독 해제 뒤 이벤트 → 무동작(누수 0)");
|
|||
|
|
if (map == null) return;
|
|||
|
|
EnvLook.UnhookHub();
|
|||
|
|
EnvLook.ResetForProbe();
|
|||
|
|
LookModeHub.SetEnvLook(false);
|
|||
|
|
EnvLook.HookHub();
|
|||
|
|
int e0 = EnvLook.HubEvents;
|
|||
|
|
Chk("E0 구독 상태", EnvLook.HubHooked && e0 == 1, "HubHooked=" + EnvLook.HubHooked + " HubEvents=" + e0);
|
|||
|
|
|
|||
|
|
bool un = EnvLook.UnhookHub();
|
|||
|
|
Chk("E1 해제", un && !EnvLook.HubHooked, "UnhookHub=" + un + " HubHooked=" + EnvLook.HubHooked);
|
|||
|
|
Chk("E2 이중 해제 무해", EnvLook.UnhookHub() == false, "두 번째 UnhookHub=false");
|
|||
|
|
|
|||
|
|
LookModeHub.SetEnvLook(true);
|
|||
|
|
int grass = map.GetComponentsInChildren<global::Environment.Instancing.MeshInstancesBehaviour>(true).Length;
|
|||
|
|
Chk("E3 해제 뒤 ON 이벤트 무동작", EnvLook.HubEvents == e0 && !EnvLook.IsApplied && EnvLook.SwappedRenderers == 0 && grass == 0,
|
|||
|
|
"HubEvents=" + EnvLook.HubEvents + "(해제 시점 " + e0 + ") · IsApplied=" + EnvLook.IsApplied +
|
|||
|
|
" · 렌더러 " + EnvLook.SwappedRenderers + " · 잔디 " + grass);
|
|||
|
|
LookModeHub.SetEnvLook(false);
|
|||
|
|
Chk("E4 해제 뒤 OFF 이벤트 무동작", EnvLook.HubEvents == e0, "HubEvents=" + EnvLook.HubEvents);
|
|||
|
|
|
|||
|
|
// 재구독 → 다시 산다(핸들러가 남아 두 번 불리지 않는다)
|
|||
|
|
EnvLook.HookHub();
|
|||
|
|
int e1 = EnvLook.HubEvents;
|
|||
|
|
LookModeHub.SetEnvLook(true);
|
|||
|
|
Chk("E5 재구독 → 이벤트 정확히 1회", EnvLook.HubEvents == e1 + 1, "HubEvents " + e1 + " → " + EnvLook.HubEvents);
|
|||
|
|
LookModeHub.SetEnvLook(false);
|
|||
|
|
EnvLook.UnhookHub();
|
|||
|
|
EnvLook.ResetForProbe();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// ── F. ⓕ GC 0 ───────────────────────────────────────────────────────────
|
|||
|
|
static void F_Gc()
|
|||
|
|
{
|
|||
|
|
L("");
|
|||
|
|
L("## F. ⓕ GC — 브리지 게이트 경로 (허브 OFF · 맵 없음)");
|
|||
|
|
EnvLook.UnhookHub();
|
|||
|
|
EnvLook.ResetForProbe();
|
|||
|
|
LookModeHub.SetEnvLook(false);
|
|||
|
|
|
|||
|
|
for (int i = 0; i < 1000; i++) { EnvLook.MapEnter(); EnvLook.TickForProbe(); } // 워밍업
|
|||
|
|
GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect();
|
|||
|
|
long m0 = Profiler.GetMonoUsedSizeLong(), t0 = GC.GetTotalMemory(false);
|
|||
|
|
int g0 = GC.CollectionCount(0);
|
|||
|
|
for (int i = 0; i < 200000; i++) EnvLook.MapEnter();
|
|||
|
|
for (int i = 0; i < 200000; i++) { if (EnvLook.FollowHub && EnvLook.HubHooked) { } }
|
|||
|
|
for (int i = 0; i < 200000; i++) EnvLook.TickForProbe();
|
|||
|
|
long m1 = Profiler.GetMonoUsedSizeLong(), t1 = GC.GetTotalMemory(false);
|
|||
|
|
int g1 = GC.CollectionCount(0);
|
|||
|
|
Chk("F1 MapEnter/FollowHub/Tick ×200k GC 0", (m1 - m0) == 0 && (t1 - t0) == 0 && (g1 - g0) == 0,
|
|||
|
|
"monoΔ " + (m1 - m0) + " B · totalΔ " + (t1 - t0) + " B · gen0 " + (g1 - g0) + " · HubGated=" + EnvLook.HubGated);
|
|||
|
|
EnvLook.ResetForProbe();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// ── G. ⓕ C8 (WLEnvLookSettings.enabled 0 → 브리지 무동작) ────────────────
|
|||
|
|
static void G_C8(GameObject map)
|
|||
|
|
{
|
|||
|
|
L("");
|
|||
|
|
L("## G. ⓕ C8 — WLEnvLookSettings.enabled = 0 → 브리지 무동작");
|
|||
|
|
if (map == null) return;
|
|||
|
|
EnvLook.UnhookHub();
|
|||
|
|
EnvLook.ResetForProbe();
|
|||
|
|
LookModeHub.SetEnvLook(false);
|
|||
|
|
var before = Snapshot(map);
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
WLEnvLookSettings.RuntimeDisabled = true; // = 에셋 enabled 0 과 같은 게이트
|
|||
|
|
Chk("G0 게이트 off", !WLEnvLookSettings.Enabled, "Enabled=" + WLEnvLookSettings.Enabled);
|
|||
|
|
|
|||
|
|
EnvLook.HookHub();
|
|||
|
|
LookModeHub.SetEnvLook(true); // [배경] ON 상당
|
|||
|
|
int grass = map.GetComponentsInChildren<global::Environment.Instancing.MeshInstancesBehaviour>(true).Length;
|
|||
|
|
Chk("G1 이벤트를 받아도 적용 0", !EnvLook.IsApplied && EnvLook.SwappedRenderers == 0 && grass == 0,
|
|||
|
|
"IsApplied=" + EnvLook.IsApplied + " · 렌더러 " + EnvLook.SwappedRenderers + " · 잔디 " + grass +
|
|||
|
|
" · HubEvents=" + EnvLook.HubEvents);
|
|||
|
|
Chk("G2 경계도 적용 0", EnvLook.MapEnter() == false && !EnvLook.IsApplied, "MapEnter=false");
|
|||
|
|
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++; }
|
|||
|
|
Chk("G3 머티리얼 무변경", mismatch == 0, "불일치 " + mismatch + "/" + before.Count);
|
|||
|
|
EnvLook.EnsureRunnerForProbe();
|
|||
|
|
int runners = 0;
|
|||
|
|
foreach (var go in UnityEngine.Object.FindObjectsByType<GameObject>(FindObjectsInactive.Include, FindObjectsSortMode.None))
|
|||
|
|
if (go.name.StartsWith("[WL814c]")) runners++;
|
|||
|
|
Chk("G4 러너 오브젝트 0", runners == 0, runners + "개");
|
|||
|
|
}
|
|||
|
|
finally
|
|||
|
|
{
|
|||
|
|
WLEnvLookSettings.RuntimeDisabled = false;
|
|||
|
|
LookModeHub.SetEnvLook(false);
|
|||
|
|
EnvLook.UnhookHub();
|
|||
|
|
EnvLook.ResetForProbe();
|
|||
|
|
}
|
|||
|
|
Chk("G5 게이트 복구", WLEnvLookSettings.Enabled, "Enabled=" + WLEnvLookSettings.Enabled);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// ── 헬퍼 ────────────────────────────────────────────────────────────────
|
|||
|
|
static bool Chk2(string n, bool ok, string d) { Chk(n, ok, d); return ok; }
|
|||
|
|
|
|||
|
|
static Dictionary<int, string> Snapshot(GameObject root)
|
|||
|
|
{
|
|||
|
|
var d = new Dictionary<int, string>();
|
|||
|
|
foreach (var r in root.GetComponentsInChildren<Renderer>(true))
|
|||
|
|
{
|
|||
|
|
var sb = new StringBuilder();
|
|||
|
|
foreach (var m in r.sharedMaterials) sb.Append(m != null ? m.name : "(null)").Append('|');
|
|||
|
|
d[r.GetInstanceID()] = sb.ToString();
|
|||
|
|
}
|
|||
|
|
return d;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static GameObject Inst(string path)
|
|||
|
|
{
|
|||
|
|
var src = AssetDatabase.LoadAssetAtPath<GameObject>(path);
|
|||
|
|
if (src == null) { L(" 프리팹 없음 " + path); return null; }
|
|||
|
|
var go = (GameObject)PrefabUtility.InstantiatePrefab(src);
|
|||
|
|
go.transform.position = Vector3.zero;
|
|||
|
|
return go;
|
|||
|
|
}
|
|||
|
|
}
|