EerieVillage/Assets/Scripts/Skills/Effectors/HitboxDebug.cs

89 lines
4.0 KiB
C#
Raw Permalink Normal View History

using UnityEngine;
namespace EerieVillage.Skills.Effectors
{
/// <summary>
/// PD 지시 2026-05-13 — 모든 액티브 스킬 판정 영역 시각화 공용 helper.
/// 붉은 반투명 박스 (1×1 white sprite·color 1,0,0,0.35) 를 size 만큼 scale.
/// </summary>
public static class HitboxDebug
{
// PD 지시 2026-05-18 — 판정 체크 영역 붉은 박스 시각화 off (BT12-Dev-Clone 후속).
feat(BT12-Dev): 박스 시각화 ON + 맵 경계 멈춤 진단 로그 (PD 지시 2026-05-14) PD 보고 2건: 1. "투사체 판정 범위를 다시 보여줘" 2. "파이어볼이나 저주의 화살과 같은 투사체 형태는 여전히 맵이 연결되는 경계선을 넘지 못하고 제자리에서 멈추다가 소멸하고 있어. (단, 속도가 느린 투사체는 정상적으로 날아감)" 정정: 1. HitboxDebug.ShowDebugVisuals false → true - Range_Debug (파란 박스)·ProjectileHitbox_Debug (붉은 박스)· LaserHitbox_Debug·MeleeHitbox_Debug·Hitbox_Debug 일괄 노출. - SpriteRenderer.enabled toggle 만 — GameObject·LiveHitboxSync 부착 정상. 2. Projectile.OnTriggerEnter2D Wall hit 시 + Update Wall OverlapPoint hit 시 진단 Debug.Log 추가: - [Projectile][WallHit-OnTrigger] cardId·other.name·parent·layer· isTrigger·pos·dist/maxRange - [Projectile][WallHit-OverlapPoint] cardId·hit.name·parent·layer· pos·dist/maxRange PD Play 후 Console "[Projectile][WallHit-*]" 로그 + 박스 시각으로 어떤 collider 가 빠른 투사체 (A02·A08·A14·A15) 를 차단하는지 정확 식별. 본 PM 후속 정정 시 회수 의무. 원인 가설: 직전 commit 708ba08 Layer 16 제외 후에도 잔존 → 다른 collider (CinemachineConfiner Trigger·InfiniteHorizontalGround Left/Right 자식·Background segment 등) hit 가능성. A13 (속도 2.5) 정상·A02 (속도 6)·A08 영역 차단 — 빠른 투사체에서만 재현 패턴 정합. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 13:06:15 +00:00
// GameObject·LiveHitboxSync 부착 정상 — SpriteRenderer 활성화만 toggle.
public static bool ShowDebugVisuals = false;
/// <summary>지정 world 좌표·size 박스 spawn·lifetime 후 destroy. lifetime=0 영역 영구.</summary>
public static GameObject Spawn(Vector2 pos, Vector2 size, float lifetime)
{
var go = new GameObject("Hitbox_Debug");
// PD 지시 2026-05-13 — 런타임 spawn 박스 Scene 저장 회피 (Edit Mode execute 시 잔존 방지)
go.hideFlags = HideFlags.DontSave;
go.transform.position = (Vector3)pos;
go.transform.localScale = new Vector3(size.x, size.y, 1f);
AttachSprite(go);
if (lifetime > 0f) Object.Destroy(go, lifetime);
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;
sr.enabled = ShowDebugVisuals;
if (lifetime > 0f) Object.Destroy(go, lifetime);
return go;
}
/// <summary>지정 Transform 의 자식으로 박스 attach (target 이동 시 함께 이동·scale 은 size 그대로 유지).</summary>
public static GameObject AttachToTransform(Transform target, Vector2 size)
{
var go = new GameObject("Hitbox_Debug");
go.hideFlags = HideFlags.DontSave;
go.transform.SetParent(target, false);
go.transform.localPosition = Vector3.zero;
// parent lossyScale 보정 — local scale 환산
float px = target.lossyScale.x != 0f ? Mathf.Abs(target.lossyScale.x) : 1f;
float py = target.lossyScale.y != 0f ? Mathf.Abs(target.lossyScale.y) : 1f;
go.transform.localScale = new Vector3(size.x / px, size.y / py, 1f);
AttachSprite(go);
return go;
}
static void AttachSprite(GameObject go)
{
var sr = go.AddComponent<SpriteRenderer>();
sr.sprite = GetWhiteSprite();
sr.color = new Color(1f, 0f, 0f, 0.35f);
sr.sortingOrder = 100;
sr.enabled = ShowDebugVisuals;
}
static Sprite _whiteSprite;
public static Sprite GetWhiteSprite()
{
if (_whiteSprite != null) return _whiteSprite;
var tex = new Texture2D(2, 2, TextureFormat.RGBA32, false);
var pixels = new Color[4];
for (int i = 0; i < 4; i++) pixels[i] = Color.white;
tex.SetPixels(pixels);
tex.Apply();
_whiteSprite = Sprite.Create(tex, new Rect(0, 0, 2, 2), new Vector2(0.5f, 0.5f), 2);
return _whiteSprite;
}
}
}