From 33eaa55c60328a7a7674acdaa3b69c47acfbd2ff Mon Sep 17 00:00:00 2001 From: swrring Date: Sat, 9 May 2026 21:50:02 +0900 Subject: [PATCH] =?UTF-8?q?fix(BT12-Dev):=20=EC=9E=94=EC=A1=B4=20=ED=88=AC?= =?UTF-8?q?=EC=82=AC=EC=B2=B4=20=EA=B7=BC=EB=B3=B8=20=ED=95=B4=EA=B2=B0=20?= =?UTF-8?q?=E2=80=94=20fallback=20Scene=20GameObject=20Instantiate=20?= =?UTF-8?q?=ED=8C=A8=ED=84=B4=20=EC=A0=95=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 근본 원인: - Resources/Skills/Projectiles/Default.prefab 부재 - LoadProjectilePrefab fallback이 new GameObject로 Scene 영역 GameObject 생성·반환 - ProjectileSpawner.Trigger가 이를 prefab으로 Object.Instantiate → 사본은 정상 SelfDestruct → 원본 Scene GameObject는 Initialize 미호출 → _lifetime Invoke 미설정 → 영구 잔존 해결 (옵션 J): - LoadProjectilePrefab은 Resources prefab만 반환 (부재 시 null) - ProjectileSpawner.Trigger가 prefab null 시 CreateFallbackProjectile 직접 호출 - fallback 영역 매번 새 GameObject 직접 생성 (Instantiate X·자기 자신 발사체) - 원본 Scene GameObject 잔존 패턴 근본 차단 검증: - Glob 0건: Assets/Resources/Skills/Projectiles/ 부재 확인 - pm-auditor Pass + Minor 1 + Improvement 1 (회귀 위험 0건) PD 보고 (2026-05-09): "맵에 투사체 하나가 영구적으로 남아있어" 근본 해결. --- .../Skills/Effectors/ProjectileSpawner.cs | 40 +++++++++++-------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/Assets/Scripts/Skills/Effectors/ProjectileSpawner.cs b/Assets/Scripts/Skills/Effectors/ProjectileSpawner.cs index 88ac6d0..8c67219 100644 --- a/Assets/Scripts/Skills/Effectors/ProjectileSpawner.cs +++ b/Assets/Scripts/Skills/Effectors/ProjectileSpawner.cs @@ -27,13 +27,8 @@ namespace EerieVillage.Skills.Effectors var pc = inventory.GetComponent(); if (pc != null) facing = pc.Facing; - // 프리팹 로드 - GameObject prefab = LoadProjectilePrefab(data); - if (prefab == null) - { - Debug.LogWarning($"[ProjectileSpawner] 투사체 프리팹 로드 실패 (data.id={data.CardId})"); - return; - } + // 프리팹 로드 (없으면 fallback — Trigger 영역에서 직접 생성) + GameObject prefab = LoadProjectilePrefab(); // 다중 발사 수 (기본 1 + ExtraProjectiles) int count = 1 + Mathf.Max(0, inventory.Stats.ExtraProjectiles); @@ -45,7 +40,12 @@ namespace EerieVillage.Skills.Effectors float angle = startAngle + angleStep * i; Vector2 dir = RotateVector(facing, angle); - var go = Object.Instantiate(prefab, (Vector3)spawnPos, Quaternion.identity); + // BT12-Dev 2026-05-09 잔존 투사체 fix: + // prefab 부재 시 Scene GameObject를 prefab으로 Instantiate하면 원본 Scene GO가 잔존. + // → fallback 영역 매번 새 GameObject 직접 생성 (Instantiate X·자기 자신 발사체). + GameObject go = prefab != null + ? Object.Instantiate(prefab, (Vector3)spawnPos, Quaternion.identity) + : CreateFallbackProjectile(data, (Vector3)spawnPos); Projectile proj; if (data.Trajectory == ProjectileTrajectory.Homing) @@ -58,19 +58,25 @@ namespace EerieVillage.Skills.Effectors } /// - /// 투사체 프리팹 로드. - /// Phase 2-C 에서 data.projectilePrefab 필드를 추가하면 해당 경로 우선 사용. - /// 현재는 Resources/Skills/Projectiles/Default 폴백. - /// 폴백 실패 시 Collider2D + SpriteRenderer 부착 빈 오브젝트를 반환한다. - /// PD 지시 2026-05-09 — 시각화: 흰색 원 sprite (Unity 기본 whiteTexture 사용). + /// Resources/Skills/Projectiles/Default prefab 로드. 부재 시 null. + /// Phase 2-C 에서 data.projectilePrefab 필드를 추가하면 해당 경로 우선 사용 가능. /// - private static GameObject LoadProjectilePrefab(ActiveSkillData data) + private static GameObject LoadProjectilePrefab() { - var prefab = Resources.Load("Skills/Projectiles/Default"); - if (prefab != null) return prefab; + return Resources.Load("Skills/Projectiles/Default"); + } - // 폴백 — Collider + SpriteRenderer (시각 표시·판정 동시) + /// + /// fallback 발사체 GameObject 직접 생성. Instantiate 영역 X — 자기 자신 발사체. + /// BT12-Dev 2026-05-09 — 이전 LoadProjectilePrefab fallback 영역에서 분리. + /// 원본 Scene GameObject 영구 잔존 버그 근본 해결 (PD 보고 — 맵에 투사체 영구 잔존). + /// PD 지시 2026-05-09 시각화 — 16×16 RGBA32 동적 알파 원 Texture2D + 속성별 색상. + /// + private static GameObject CreateFallbackProjectile(ActiveSkillData data, Vector3 spawnPos) + { var go = new GameObject($"Projectile_{data.CardId}"); + go.transform.position = spawnPos; + var col = go.AddComponent(); col.isTrigger = true; col.radius = 0.2f;