From 01865b88fb4f9b9485c50e12958c1018140d61b3 Mon Sep 17 00:00:00 2001 From: swrring Date: Thu, 14 May 2026 15:43:52 +0900 Subject: [PATCH] =?UTF-8?q?feat(BT12-Dev):=20=EA=B2=8C=EC=9E=84=20?= =?UTF-8?q?=EC=9E=AC=EC=8B=A4=ED=96=89=20=EC=8B=9C=20=EC=9E=94=EC=A1=B4=20?= =?UTF-8?q?spawn=20=EA=B0=95=EC=A0=9C=20cleanup=20(PD=20=EC=A7=80=EC=8B=9C?= =?UTF-8?q?=202026-05-14)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PD 보고: "게임 플레이 중 종료했다가 다시 시작할 경우 이전 게임 플레이 중 생성 된 투사체가 여전히 남아있어. 게임을 재실행할 때 기존에 생성 된 풀링 오브젝트가 소멸될 수 있도록 수정해줘." PlayerSkillInventory.Awake 시점 CleanupStalePooledSpawns 호출: - Projectile 및 파생 (HomingProjectile·PiercingProjectile) component 부착 GameObject 전수 destroy - 박스 시각화 name 5종 (Hitbox_Debug·ProjectileHitbox_Debug· LaserHitbox_Debug·MeleeHitbox_Debug·Range_Debug) destroy - Resources.FindObjectsOfTypeAll + scene.IsValid filter (asset prefab 제외) - removed 카운트 Debug.Log 기존 HideFlags.DontSave (60e28e3) 정합 외 추가 보험: - DontDestroyOnLoad 경로 (코드베이스 검색 0건 — 방어 코드) - Scene 영구 저장 누락 케이스 - 메모리 잔존 (Editor crash 후 재시작 등) 검증 (Play 모드): - A02·A05 발사 후 spawn 카운트 6 - CleanupStalePooledSpawns 직접 호출 + 1 frame 후 카운트 0 Co-Authored-By: Claude Opus 4.7 (1M context) --- .../Skills/Runtime/PlayerSkillInventory.cs | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/Assets/Scripts/Skills/Runtime/PlayerSkillInventory.cs b/Assets/Scripts/Skills/Runtime/PlayerSkillInventory.cs index 609bf93..8eafd97 100644 --- a/Assets/Scripts/Skills/Runtime/PlayerSkillInventory.cs +++ b/Assets/Scripts/Skills/Runtime/PlayerSkillInventory.cs @@ -45,11 +45,55 @@ namespace EerieVillage.Skills void Awake() { + // PD 지시 2026-05-14 — 게임 재실행 시 이전 Play 잔존 spawn (투사체·박스·Range) 강제 cleanup. + // HideFlags.DontSave 정합 외 DontDestroyOnLoad·Scene 영구 저장·메모리 잔존 경로 방어. + CleanupStalePooledSpawns(); + Stats = new PlayerStats(); PlayerStats.Current = Stats; _health = GetComponent(); } + // PD 지시 2026-05-14 — 잔존 풀링 GameObject 강제 cleanup + // 대상: Projectile 및 파생 (HomingProjectile·PiercingProjectile) + 박스 시각화 GameObject + static readonly System.Collections.Generic.HashSet StaleSpawnNames = + new System.Collections.Generic.HashSet + { + "Hitbox_Debug", + "ProjectileHitbox_Debug", + "LaserHitbox_Debug", + "MeleeHitbox_Debug", + "Range_Debug", + }; + + void CleanupStalePooledSpawns() + { + int removed = 0; + // (1) Projectile 및 파생 component GameObject — root 단위 destroy + var projs = Resources.FindObjectsOfTypeAll(); + foreach (var p in projs) + { + if (p == null || p.gameObject == null) continue; + if (!p.gameObject.scene.IsValid()) continue; // prefab asset 제외 + Destroy(p.gameObject); + removed++; + } + // (2) 박스 시각화 — name 기반 (자체 부착 컴포넌트 부재 케이스) + var allGOs = Resources.FindObjectsOfTypeAll(); + foreach (var go in allGOs) + { + if (go == null) continue; + if (!go.scene.IsValid()) continue; + if (StaleSpawnNames.Contains(go.name)) + { + Destroy(go); + removed++; + } + } + if (removed > 0) + Debug.Log("[PlayerSkillInventory] CleanupStalePooledSpawns removed=" + removed); + } + // PD 지시 2026-05-13 — Start 시점에 기본 습득 스킬 자동 장착 (Resources 로드 완료 후·Awake 영역 아님) void Start() {