From ab40b2777364050f149e3c01ece8bd0fa6c741e5 Mon Sep 17 00:00:00 2001 From: swrring Date: Wed, 13 May 2026 19:00:29 +0900 Subject: [PATCH] =?UTF-8?q?feat(BT12-Dev):=20=ED=88=AC=EC=82=AC=EC=B2=B4?= =?UTF-8?q?=20=EC=82=AC=EA=B1=B0=EB=A6=AC=20=EC=8B=9C=EA=B0=81=ED=99=94?= =?UTF-8?q?=C2=B7Inspector=20=EC=A1=B0=EC=A0=88=C2=B7A04=20Extra=20FX=20(P?= =?UTF-8?q?D=20=EC=A7=80=EC=8B=9C=202026-05-13)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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) --- Assets/Scripts/Skills/Data/ActiveSkillData.cs | 16 +++++++++++++- .../Scripts/Skills/Effectors/HitboxDebug.cs | 22 +++++++++++++++++++ .../Effectors/LightningStrikeSpawner.cs | 18 +++++++++++++++ .../Skills/Effectors/PiercingProjectile.cs | 2 +- Assets/Scripts/Skills/Effectors/Projectile.cs | 19 +++++----------- 5 files changed, 62 insertions(+), 15 deletions(-) diff --git a/Assets/Scripts/Skills/Data/ActiveSkillData.cs b/Assets/Scripts/Skills/Data/ActiveSkillData.cs index 5cdabc1..8d32e7c 100644 --- a/Assets/Scripts/Skills/Data/ActiveSkillData.cs +++ b/Assets/Scripts/Skills/Data/ActiveSkillData.cs @@ -81,9 +81,19 @@ namespace EerieVillage.Skills public float FireProbability = 1.0f; /// BT12-Dev 2026-05-10 PD — 사정거리 5단계 (Camera width 배수) - [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; diff --git a/Assets/Scripts/Skills/Effectors/HitboxDebug.cs b/Assets/Scripts/Skills/Effectors/HitboxDebug.cs index ccb8c7f..f57307f 100644 --- a/Assets/Scripts/Skills/Effectors/HitboxDebug.cs +++ b/Assets/Scripts/Skills/Effectors/HitboxDebug.cs @@ -21,6 +21,28 @@ namespace EerieVillage.Skills.Effectors return go; } + /// + /// PD 지시 2026-05-13 — 투사체 사거리 시각화. spawnPos 부터 dir 방향 range 길이 파란 박스. + /// 색상 (0, 0.45, 1, 0.35) 반투명·발사 후 lifetime 후 자동 destroy. + /// + 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(); + 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; + } + /// 지정 Transform 의 자식으로 박스 attach (target 이동 시 함께 이동·scale 은 size 그대로 유지). public static GameObject AttachToTransform(Transform target, Vector2 size) { diff --git a/Assets/Scripts/Skills/Effectors/LightningStrikeSpawner.cs b/Assets/Scripts/Skills/Effectors/LightningStrikeSpawner.cs index e91aa9d..e909fe2 100644 --- a/Assets/Scripts/Skills/Effectors/LightningStrikeSpawner.cs +++ b/Assets/Scripts/Skills/Effectors/LightningStrikeSpawner.cs @@ -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(); diff --git a/Assets/Scripts/Skills/Effectors/PiercingProjectile.cs b/Assets/Scripts/Skills/Effectors/PiercingProjectile.cs index 284a7ee..fdc8f70 100644 --- a/Assets/Scripts/Skills/Effectors/PiercingProjectile.cs +++ b/Assets/Scripts/Skills/Effectors/PiercingProjectile.cs @@ -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(); diff --git a/Assets/Scripts/Skills/Effectors/Projectile.cs b/Assets/Scripts/Skills/Effectors/Projectile.cs index 7b5d663..11b4260 100644 --- a/Assets/Scripts/Skills/Effectors/Projectile.cs +++ b/Assets/Scripts/Skills/Effectors/Projectile.cs @@ -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(); _mpb = new MaterialPropertyBlock();