feat(BT12-Dev): 투사체 사거리 시각화·Inspector 조절·A04 Extra FX (PD 지시 2026-05-13)

- HitboxDebug.SpawnRange 신규 — 투사체 사거리 파란 박스 (3초 유지·HideFlags.DontSave)
- Projectile._speed·_maxRange = ActiveSkillData.ProjectileSpeed·MaxRange Inspector 직접 (RangeTier·camWidth·mults 계산 폐기)
- PiercingProjectile._speed override 2.5f 폐기 — data.ProjectileSpeed 정합
- ActiveSkillData 신규 필드 3 — MaxRange·ProjectileSpeed·ExtraHitFxPrefab
- LightningStrikeSpawner — ExtraHitFxPrefab 0.6초 후 spawn·y -0.5 (A04 FX_Thunder Smoke 비주얼 전용·판정 무관)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
깃 관리자 2026-05-13 19:00:29 +09:00
parent 4881c6657e
commit ab40b27773
5 changed files with 62 additions and 15 deletions

View File

@ -81,9 +81,19 @@ namespace EerieVillage.Skills
public float FireProbability = 1.0f;
/// <summary>BT12-Dev 2026-05-10 PD — 사정거리 5단계 (Camera width 배수)</summary>
[Tooltip("사정거리 5단계 — Camera 가로 배수 (Short 0.2·MediumShort 0.5·Medium 0.667·MediumLong 1.0·Long 1.5)")]
[Tooltip("[잠정 유지] 5 . MaxRange ")]
public RangeTier Range = RangeTier.Medium;
// PD 지시 2026-05-13 — 투사체형 스킬 Inspector 조절 (사정거리·속도)
[Header("투사체 사거리·속도 (Inspector 조절)")]
[Tooltip("투사체 사정거리 (unit). 0 이하 시 fallback 10")]
[Min(0f)]
public float MaxRange = 10f;
[Tooltip("투사체 비행 속도 (unit/sec). 0 이하 시 fallback 6")]
[Min(0f)]
public float ProjectileSpeed = 6f;
// BT12-Dev 2026-05-13 — 스킬 이펙트 prefab 3 + DoT damage multiplier (PD 지시: A02 파이어볼 이펙트 구현)
[Header("스킬 이펙트 (Phase 2-E)")]
[Tooltip("투사체 prefab — 부재 시 Resources/Skills/Projectiles/Default fallback")]
@ -92,6 +102,10 @@ namespace EerieVillage.Skills
[Tooltip("적중 시 Instantiate 되는 ParticleSystem prefab (적 위치)")]
public GameObject OnHitFxPrefab;
// PD 지시 2026-05-13 — A04 번개 충격 피격 이펙트에 FX_Thunder Smoke 추가 (비주얼만)
[Tooltip("추가 피격 FX — 비주얼 전용 (예: A04 번개 충격 FX_Thunder Smoke 동반 spawn)")]
public GameObject ExtraHitFxPrefab;
[Tooltip("DoT 적용 시 적 자식으로 Instantiate 되는 ParticleSystem prefab")]
public GameObject OnDotFxPrefab;

View File

@ -21,6 +21,28 @@ namespace EerieVillage.Skills.Effectors
return go;
}
/// <summary>
/// PD 지시 2026-05-13 — 투사체 사거리 시각화. spawnPos 부터 dir 방향 range 길이 파란 박스.
/// 색상 (0, 0.45, 1, 0.35) 반투명·발사 후 lifetime 후 자동 destroy.
/// </summary>
public static GameObject SpawnRange(Vector2 spawnPos, Vector2 dir, float range, float lifetime, float thickness = 0.3f)
{
var go = new GameObject("Range_Debug");
go.hideFlags = HideFlags.DontSave;
Vector2 dirN = dir.normalized;
Vector2 center = spawnPos + dirN * (range * 0.5f);
go.transform.position = (Vector3)center;
float angle = Mathf.Atan2(dirN.y, dirN.x) * Mathf.Rad2Deg;
go.transform.rotation = Quaternion.Euler(0f, 0f, angle);
go.transform.localScale = new Vector3(range, thickness, 1f);
var sr = go.AddComponent<SpriteRenderer>();
sr.sprite = GetWhiteSprite();
sr.color = new Color(0f, 0.45f, 1f, 0.35f);
sr.sortingOrder = 99;
if (lifetime > 0f) Object.Destroy(go, lifetime);
return go;
}
/// <summary>지정 Transform 의 자식으로 박스 attach (target 이동 시 함께 이동·scale 은 size 그대로 유지).</summary>
public static GameObject AttachToTransform(Transform target, Vector2 size)
{

View File

@ -71,6 +71,13 @@ namespace EerieVillage.Skills.Effectors
// 박스 즉시 spawn (rotation=0 — FxRotation 미적용)
HitboxDebug.Spawn(hitboxPos, capturedSize, Mathf.Max(data.BaseCooldown, 1f));
// PD 지시 2026-05-13 — ExtraHitFxPrefab 0.6초 후 spawn·y -0.5 오프셋 (판정 시점 무관·비주얼 전용)
if (data.ExtraHitFxPrefab != null)
{
Vector2 extraFxPos = fxPos + new Vector2(0f, -0.5f);
inventory.StartCoroutine(DelayedExtraHitFx(data, extraFxPos, 0.6f));
}
// PD 지시 2026-05-13 — ScriptableObject DamageFrameDelay·반복 피해 정합
inventory.StartCoroutine(FixedHitDamageCoroutine(hitboxPos, capturedSize, 0f, capturedDamage, data));
}
@ -92,6 +99,17 @@ namespace EerieVillage.Skills.Effectors
}
}
// PD 지시 2026-05-13 — ExtraHitFxPrefab 지연 spawn (비주얼 전용·판정 무관)
static System.Collections.IEnumerator DelayedExtraHitFx(ActiveSkillData data, Vector2 fxPos, float delaySeconds)
{
yield return new WaitForSeconds(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;
extraFx.transform.localScale *= data.HitFxScale;
AutoDestroyFx(extraFx, GetFxLifetime(extraFx));
}
static void DoOverlapBoxDamage(Vector2 pos, Vector2 size, float rotZ, int damage)
{
var cf = new ContactFilter2D();

View File

@ -22,7 +22,7 @@ namespace EerieVillage.Skills.Effectors
public override void Initialize(ActiveSkillRuntime runtime, PlayerSkillInventory inventory, Vector2 direction)
{
base.Initialize(runtime, inventory, direction);
_speed = 2.5f; // PD 지시 2026-05-13 — A13 천둥발 천천히 전진 (기본 6 → 2.5)
// PD 지시 2026-05-13 — 속도 Inspector 조절 영역 전환·_speed override 폐기 (data.ProjectileSpeed 정합)
_lifetime = 6f; // 관통이므로 lifetime 길게
_lastHitTime.Clear();

View File

@ -55,19 +55,9 @@ namespace EerieVillage.Skills.Effectors
_spawnPosition = transform.position;
_spawnTime = Time.time;
// BT12-Dev 2026-05-10 PD — 사정거리 5단계 (Camera 가로 배수)
float camWidth = 12.44f; // fallback (ortho size 3.5·16:9)
var cam = Camera.main;
if (cam != null && cam.orthographic)
{
float aspect = (cam.aspect > 0.01f) ? cam.aspect : (16f / 9f);
camWidth = cam.orthographicSize * 2f * aspect;
}
// BT12-Dev 2026-05-10 Camera ortho 3.5→5.0 정합 정정 (camWidth 12.44→17.78·1.43배).
// 기존 maxRange 동등 유지 위해 mults 1/1.43 비례 축소.
float[] mults = { 0.14f, 0.35f, 0.467f, 0.7f, 1.05f };
int idx = Mathf.Clamp((int)_data.Range, 0, mults.Length - 1);
_maxRange = camWidth * mults[idx];
// PD 지시 2026-05-13 — 투사체 사정거리·속도 Inspector 직접 조절 (RangeTier·camWidth·mults 계산 폐기)
_maxRange = (_data.MaxRange > 0.01f) ? _data.MaxRange : 10f;
_speed = (_data.ProjectileSpeed > 0.01f) ? _data.ProjectileSpeed : 6f;
// PD 정합 2026-05-13 — Inspector ProjFxScale 매 frame 영역 영역 _originalScale 저장
_originalScale = transform.localScale;
@ -77,6 +67,9 @@ namespace EerieVillage.Skills.Effectors
// PD 지시 2026-05-13 — 판정 영역 시각화 (자체 Collider2D bounds 영역 자식 박스·이동·페이드 정합)
SpawnHitboxDebugChild();
// PD 지시 2026-05-13 — 투사체 사거리 파란 박스 시각화 (발사 후 3초 유지)
HitboxDebug.SpawnRange(_spawnPosition, _direction, _maxRange, 3f);
// Renderer·MaterialPropertyBlock 캐싱 + 기본 alpha 저장
_renderers = GetComponentsInChildren<Renderer>();
_mpb = new MaterialPropertyBlock();