[WL-816d] 던전 씬 단독 Play 가드 + 치비 컴포넌트 제거 견고화 (#816)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
깃 관리자 2026-09-13 12:26:42 +09:00
parent c2972b5264
commit c23fdeb91a
6 changed files with 61 additions and 24 deletions

View File

@ -1,2 +1,8 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 736faf4adc74e2343aefce8a1281a933 guid: 736faf4adc74e2343aefce8a1281a933
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,2 +1,8 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: ac3fb08ed9e62af4295fd6ddc45d9ef8 guid: ac3fb08ed9e62af4295fd6ddc45d9ef8
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,2 +1,8 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: c1c85be0c23fb5a4ba3db7b9b8308fd5 guid: c1c85be0c23fb5a4ba3db7b9b8308fd5
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -20,6 +20,7 @@ using System.Collections.Generic;
using TMPro; using TMPro;
using Unity.AI.Navigation; using Unity.AI.Navigation;
using UnityEngine; using UnityEngine;
using UnityEngine.AI;
using UnityEngine.SceneManagement; using UnityEngine.SceneManagement;
using WL.Combat.Stage; using WL.Combat.Stage;
@ -51,6 +52,15 @@ namespace WL.Island
// ① NavMesh // ① NavMesh
if (cfg.bakeDungeonNavMesh != 0) BakeNavMesh(cfg, scene); if (cfg.bakeDungeonNavMesh != 0) BakeNavMesh(cfg, scene);
// 🔴 단독 Play(씬만 열고 Play = 룩 확인 경로)에는 테이블·ServerData 가 없다.
// 스포너·스테이지는 원본 테이블을 타므로 여기서 멈춘다 — 씬 룩만 확인한다.
if (InGameInfo.Ins == null)
{
LastLog = "던전 씬 단독 Play — 룩만 확인(스포너·스테이지 건너뜀)";
WLIslandBridge.Log(cfg, LastLog);
yield break;
}
// ② 스포너 — 스테이지 표가 요구하는 ID 로만 만든다 // ② 스포너 — 스테이지 표가 요구하는 ID 로만 만든다
s_made.Clear(); s_made.Clear();
var def = StageDefOf(d); var def = StageDefOf(d);

View File

@ -79,7 +79,6 @@ namespace WL.Island
{ {
if (s_runner != null) return; if (s_runner != null) return;
var go = new GameObject("~WLIslandRunner"); var go = new GameObject("~WLIslandRunner");
go.hideFlags = HideFlags.HideAndDontSave;
Object.DontDestroyOnLoad(go); Object.DontDestroyOnLoad(go);
s_runner = go.AddComponent<WLIslandRunner>(); s_runner = go.AddComponent<WLIslandRunner>();
} }

View File

@ -145,29 +145,39 @@ namespace WL.Island
/// <summary>전투/이동 컴포넌트를 떼어 낸다 — 남기는 것은 Animator · 렌더러 · WL 룩/크기 보정뿐.</summary> /// <summary>전투/이동 컴포넌트를 떼어 낸다 — 남기는 것은 Animator · 렌더러 · WL 룩/크기 보정뿐.</summary>
static void StripCombatComponents(GameObject root) static void StripCombatComponents(GameObject root)
{ {
var mbs = root.GetComponentsInChildren<MonoBehaviour>(true); // 🔴 [RequireComponent] 의존 때문에 순서에 따라 삭제가 거부될 수 있다 → 2회 훑고 개별 try
for (int i = 0; i < mbs.Length; i++) for (int pass = 0; pass < 2; pass++)
{ {
var mb = mbs[i]; var mbs = root.GetComponentsInChildren<MonoBehaviour>(true);
if (mb == null) continue; for (int i = 0; i < mbs.Length; i++)
if (mb is WL.Character.WLPcScaleCompensator) continue; // 높이 1.1912 m 유지 {
if (mb is WL.Look.Character.WLCharacterLook) continue; // 팔레트 UV 도트화(814x) 유지 var mb = mbs[i];
Object.DestroyImmediate(mb); if (mb == null) continue;
if (mb is WL.Character.WLPcScaleCompensator) continue; // 높이 1.1912 m 유지
if (mb is WL.Look.Character.WLCharacterLook) continue; // 팔레트 UV 도트화(814x) 유지
Kill(mb);
}
} }
var cc = root.GetComponent<CharacterController>(); if (cc != null) Object.DestroyImmediate(cc); KillAll(root.GetComponentsInChildren<UnityEngine.AI.NavMeshAgent>(true));
var agents = root.GetComponentsInChildren<UnityEngine.AI.NavMeshAgent>(true); KillAll(root.GetComponentsInChildren<UnityEngine.AI.NavMeshObstacle>(true));
for (int i = 0; i < agents.Length; i++) if (agents[i] != null) Object.DestroyImmediate(agents[i]); KillAll(root.GetComponentsInChildren<Rigidbody>(true));
var obs = root.GetComponentsInChildren<UnityEngine.AI.NavMeshObstacle>(true); KillAll(root.GetComponentsInChildren<Collider>(true)); // CharacterController 포함
for (int i = 0; i < obs.Length; i++) if (obs[i] != null) Object.DestroyImmediate(obs[i]); KillAll(root.GetComponentsInChildren<AudioSource>(true));
var rbs = root.GetComponentsInChildren<Rigidbody>(true); KillAll(root.GetComponentsInChildren<AudioListener>(true));
for (int i = 0; i < rbs.Length; i++) if (rbs[i] != null) Object.DestroyImmediate(rbs[i]); }
var cols = root.GetComponentsInChildren<Collider>(true);
for (int i = 0; i < cols.Length; i++) if (cols[i] != null) Object.DestroyImmediate(cols[i]); static void KillAll<T>(T[] arr) where T : Component
var srcs = root.GetComponentsInChildren<AudioSource>(true); {
for (int i = 0; i < srcs.Length; i++) if (srcs[i] != null) Object.DestroyImmediate(srcs[i]); if (arr == null) return;
var listeners = root.GetComponentsInChildren<AudioListener>(true); for (int i = 0; i < arr.Length; i++) Kill(arr[i]);
for (int i = 0; i < listeners.Length; i++) if (listeners[i] != null) Object.DestroyImmediate(listeners[i]); }
static void Kill(Component c)
{
if (c == null) return;
try { Object.DestroyImmediate(c); }
catch (System.Exception) { var b = c as Behaviour; if (b != null) b.enabled = false; }
} }
static int HideFiModel(WLIslandSettings cfg, GameObject fiPlayer, GameObject exclude) static int HideFiModel(WLIslandSettings cfg, GameObject fiPlayer, GameObject exclude)