feat(BT12-Dev): MeleeArea 실전 발사 연결 + FX AutoDestroy unscaledTime (PD 지시 2026-05-13)
작업 1 — 스킬 배워도 이펙트 X fix: - SkillFireEvent.Execute — MeleeArea case 추가 (CardId 분기·TestSkillFireOn1to5 동일 패턴) - A04 → LightningStrikeSpawner - A_Laser → LaserSpawner - 기타 → MeleeAreaSpawner 작업 2 — 맵 이동 중 이펙트 잔상 재발 fix: - 원인: Object.Destroy(fxGo, t) 영역 second timer 영역 Time.timeScale 영향·timeScale=0 (LevelUp) 영역 호출 정지 - 신규: FxAutoDestroyUnscaled MonoBehaviour — Update 영역 unscaledTime lifetime check 자가 Destroy - ProjectileSpawner·Projectile·MeleeAreaSpawner·LaserSpawner·LightningStrikeSpawner 모두 영역 Object.Destroy(fx, t) → FxAutoDestroyUnscaled.Attach - LightningStrikeSpawner.DelayedExtraHitFx — WaitForSeconds → WaitForSecondsRealtime (timeScale=0 영역 정합) 본 PM 자성 #12 — feedback_new_code_existing_system_dependency_unmeasured 위반. Object.Destroy(go, t) 영역 timeScale 영향 사전 측정 누락 (Unity 표준 API). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
41fa4e4ce7
commit
26b0666912
|
|
@ -0,0 +1,37 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace EerieVillage.Skills.Effectors
|
||||
{
|
||||
/// <summary>
|
||||
/// PD 지시 2026-05-13 — fx GO 영역 unscaledTime 영역 자가 Destroy.
|
||||
/// Object.Destroy(go, t) 영역 second timer 영역 Time.timeScale 영향 영역 → timeScale=0 (LevelUp 등) 영역 호출 정지·잔존.
|
||||
/// 본 컴포넌트 = Update 영역 Time.unscaledTime 영역 lifetime check → 자가 Destroy.
|
||||
/// fxGo Instantiate 직후 AddComponent 영역 lifetime 설정.
|
||||
/// </summary>
|
||||
public class FxAutoDestroyUnscaled : MonoBehaviour
|
||||
{
|
||||
public float Lifetime = 5f;
|
||||
float _spawnTime;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
_spawnTime = Time.unscaledTime;
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
if (Time.unscaledTime - _spawnTime >= Lifetime)
|
||||
{
|
||||
Destroy(gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Attach(GameObject go, float lifetime)
|
||||
{
|
||||
if (go == null) return;
|
||||
var c = go.GetComponent<FxAutoDestroyUnscaled>();
|
||||
if (c == null) c = go.AddComponent<FxAutoDestroyUnscaled>();
|
||||
c.Lifetime = Mathf.Max(0.1f, lifetime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -42,8 +42,8 @@ namespace EerieVillage.Skills.Effectors
|
|||
}
|
||||
|
||||
float fxLifetime = GetFxLifetime(fx);
|
||||
// PD 지시 2026-05-13 — fx AutoDestroy 누락 fix·safety cap 5초 (잔상 차단)
|
||||
if (fx != null) Object.Destroy(fx, Mathf.Min(fxLifetime + 0.2f, 5f));
|
||||
// PD 지시 2026-05-13 — fx AutoDestroy 누락 fix·unscaledTime cap (Time.timeScale=0 영역 잔존 차단)
|
||||
if (fx != null) FxAutoDestroyUnscaled.Attach(fx, Mathf.Min(fxLifetime + 0.2f, 5f));
|
||||
int damage = Mathf.Max(data.BaseDamage, 1);
|
||||
float length = Mathf.Max(data.HitboxSize.x, 1f);
|
||||
float width = Mathf.Max(data.HitboxSize.y, 0.5f);
|
||||
|
|
|
|||
|
|
@ -99,10 +99,10 @@ namespace EerieVillage.Skills.Effectors
|
|||
}
|
||||
}
|
||||
|
||||
// PD 지시 2026-05-13 — ExtraHitFxPrefab 지연 spawn (비주얼 전용·판정 무관)
|
||||
// PD 지시 2026-05-13 — ExtraHitFxPrefab 지연 spawn (비주얼 전용·판정 무관·WaitForSecondsRealtime 영역 Time.timeScale=0 영역 정합)
|
||||
static System.Collections.IEnumerator DelayedExtraHitFx(ActiveSkillData data, Vector2 fxPos, float delaySeconds)
|
||||
{
|
||||
yield return new WaitForSeconds(delaySeconds);
|
||||
yield return new WaitForSecondsRealtime(delaySeconds);
|
||||
if (data == null || data.ExtraHitFxPrefab == null) yield break;
|
||||
var extraFx = Object.Instantiate(data.ExtraHitFxPrefab, fxPos, Quaternion.Euler(0f, 0f, data.FxRotation));
|
||||
extraFx.hideFlags = HideFlags.DontSave;
|
||||
|
|
@ -154,8 +154,8 @@ namespace EerieVillage.Skills.Effectors
|
|||
static void AutoDestroyFx(GameObject fxGo, float lifetime)
|
||||
{
|
||||
if (fxGo == null) return;
|
||||
// PD 지시 2026-05-13 — FX 잔상 safety cap 5초
|
||||
Object.Destroy(fxGo, Mathf.Min(lifetime + 0.2f, 5f));
|
||||
// PD 지시 2026-05-13 — unscaledTime cap (Time.timeScale=0 영역 잔존 차단)
|
||||
FxAutoDestroyUnscaled.Attach(fxGo, Mathf.Min(lifetime + 0.2f, 5f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,8 +41,8 @@ namespace EerieVillage.Skills.Effectors
|
|||
// Player 자식 부착 (worldPositionStays=true) 으로 spawn 후에도 Player 이동에 동조.
|
||||
fxGo.transform.SetParent(inventory.transform, true);
|
||||
fxLifetime = GetFxLifetime(fxGo);
|
||||
// PD 지시 2026-05-13 — FX 잔상 safety cap 5초
|
||||
Object.Destroy(fxGo, Mathf.Min(fxLifetime + 0.2f, 5f));
|
||||
// PD 지시 2026-05-13 — unscaledTime cap (Time.timeScale=0 영역 잔존 차단)
|
||||
FxAutoDestroyUnscaled.Attach(fxGo, Mathf.Min(fxLifetime + 0.2f, 5f));
|
||||
}
|
||||
|
||||
// PD 지시 2026-05-13 — 박스 영역 Player 자식 영역 부착·매 frame Player 따라감
|
||||
|
|
|
|||
|
|
@ -312,8 +312,8 @@ namespace EerieVillage.Skills.Effectors
|
|||
var main = ps.main;
|
||||
lifetime = main.duration + main.startLifetime.constantMax + 0.2f;
|
||||
}
|
||||
// PD 지시 2026-05-13 — FX 잔상 safety cap 5초
|
||||
Object.Destroy(fxGo, Mathf.Min(lifetime, 5f));
|
||||
// PD 지시 2026-05-13 — unscaledTime cap (Time.timeScale=0 영역 잔존 차단)
|
||||
FxAutoDestroyUnscaled.Attach(fxGo, Mathf.Min(lifetime, 5f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,14 @@ namespace EerieVillage.Skills
|
|||
effector = new ProjectileSpawner();
|
||||
break;
|
||||
|
||||
// Phase 2-C~ 예정: MeleeArea·PlacementPersistent·Minion·Debuff·SpecialJudge
|
||||
// PD 지시 2026-05-13 — MeleeArea 영역 CardId 분기 (TestSkillFireOn1to5 영역 동일 패턴)
|
||||
case ActiveCategory.MeleeArea:
|
||||
if (data.CardId == "A04") effector = new LightningStrikeSpawner();
|
||||
else if (data.CardId == "A_Laser") effector = new LaserSpawner();
|
||||
else effector = new MeleeAreaSpawner();
|
||||
break;
|
||||
|
||||
// Phase 2-C~ 예정: PlacementPersistent·Minion·Debuff·SpecialJudge
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue