2026-05-18 기획 수정 : 플레이어와 에너미의 body간 충돌은 없다

This commit is contained in:
2026-05-18 11:45:03 +09:00
parent 53e7f3b302
commit ea3a4fbbcc
17 changed files with 762 additions and 410 deletions

View File

@@ -0,0 +1,66 @@
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(CircleCollider2D))]
public class AttackHitbox : MonoBehaviour
{
private CircleCollider2D _collider;
private int _damage;
private Vector2 _hitVelocity;
private string _hitReactionState;
private LayerMask _targetLayer;
private readonly HashSet<IDamageable> _alreadyHit = new();
private void Awake()
{
_collider = GetComponent<CircleCollider2D>();
// The player body does not collide with enemies; this trigger is the only attack contact.
_collider.isTrigger = true;
_collider.enabled = false;
}
public void Activate(ActionData data, Vector2 localPosition, Vector2 hitVelocity, LayerMask targetLayer)
{
transform.localPosition = localPosition;
_collider.radius = data.Radius;
_damage = data.Damage;
_hitVelocity = hitVelocity;
_hitReactionState = data.HitReactionAnimationState;
_targetLayer = targetLayer;
_alreadyHit.Clear();
_collider.enabled = true;
// Catch enemies already inside the hitbox on the same frame it opens.
ScanImmediateOverlap();
}
public void Deactivate()
{
_collider.enabled = false;
_alreadyHit.Clear();
}
private void ScanImmediateOverlap()
{
Collider2D[] hits = Physics2D.OverlapCircleAll(transform.position, _collider.radius, _targetLayer);
foreach (var hit in hits)
TryDamage(hit);
}
private void OnTriggerEnter2D(Collider2D other) => TryDamage(other);
private void OnTriggerStay2D(Collider2D other) => TryDamage(other);
private void TryDamage(Collider2D other)
{
if ((_targetLayer.value & (1 << other.gameObject.layer)) == 0) return;
// Hurtboxes may live on child objects, while damage handling usually lives on the root.
if (!other.TryGetComponent<IDamageable>(out var target))
target = other.GetComponentInParent<IDamageable>();
if (target == null) return;
if (_alreadyHit.Contains(target)) return;
_alreadyHit.Add(target);
target.TakeDamage(_damage, _hitVelocity, _hitReactionState);
}
}