[Unity] Hitbox와 Hurtbox시스템Unity/C#2022. 6. 20. 00:37
Table of Contents
결과물 영상
Hitbox는 Overlapbox를 통해 충돌을 감지하고 원하는 타이밍에 켜고 끌수있다.
(여기선 애니메이션 이벤트로 컨트롤)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Hitbox : MonoBehaviour
{
public enum ColliderState
{
Closed,
Open,
Colliding
}
public LayerMask mask;
public Vector3 hitboxSize = Vector3.one;
public Vector3 offset = Vector3.zero;
public float radius = 0.5f;
public Color inactiveColor = Color.grey;
public Color collisionOpenColor = Color.green;
public Color collidingColor = Color.magenta;
private ColliderState _state;
private IHitboxResponder responder = null;
private List<Collider> lastHitCollidersList;
private void Awake()
{
lastHitCollidersList = new List<Collider>();
}
private void CheckGizmoColor()
{
switch(_state)
{
case ColliderState.Closed:
Gizmos.color = inactiveColor;
break;
case ColliderState.Open:
Gizmos.color = collisionOpenColor;
break;
case ColliderState.Colliding:
Gizmos.color = collidingColor;
break;
}
}
public void StartCheckingCollision()
{
lastHitCollidersList.Clear();
_state = ColliderState.Open;
}
public void StopCheckingCollision()
{
_state = ColliderState.Closed;
}
public void SetResponder(IHitboxResponder newResponder)
{
responder = newResponder;
}
private void FixedUpdate()
{
if (_state == ColliderState.Closed)
return;
Vector3 size = new Vector3(
hitboxSize.x * transform.lossyScale.x,
hitboxSize.y * transform.lossyScale.y,
hitboxSize.z * transform.lossyScale.z
);
Collider[] colls = Physics.OverlapBox(transform.TransformPoint(offset), size * 0.5f, transform.rotation, mask);
for (int i = 0; i < colls.Length; i++)
{
if (lastHitCollidersList.Contains(colls[i]))
continue;
responder?.CollisionedWith(colls[i]);
lastHitCollidersList.Add(colls[i]);
}
_state = colls.Length > 0 ? ColliderState.Colliding : ColliderState.Open;
}
public interface IHitboxResponder
{
void CollisionedWith(Collider coll);
}
private void OnDrawGizmos()
{
CheckGizmoColor();
Gizmos.matrix = transform.localToWorldMatrix;
Gizmos.DrawCube(offset, hitboxSize);
}
}
Hurtbox는 콜라이더를 통해 항상 검출하는 형태로 구현
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using DG.Tweening;
public class Damageable : MonoBehaviour
{
public UnityEvent<float> onGetDamage;
public UnityEvent<DamageInfo> onGetDamageFromHitbox;
public Transform rootTransform;
public bool IsDead { get => _isDead; set => SetIsDead(value); }
[SerializeField] private bool _isDead;
public void GetDamage(float damage)
{
onGetDamage.Invoke(damage);
}
public void GetDamage(DamageInfo info)
{
onGetDamageFromHitbox.Invoke(info);
}
public void SetIsDead(bool isDead)
{
_isDead = isDead;
}
}
프로젝트 레포지토리
구현에 참고한 문서
'Unity > C#' 카테고리의 다른 글
[Unity, C#] 박스 콜라이더안에 랜덤포인트 구하기 (0) | 2022.10.01 |
---|---|
[C#] Enum에 Contains인지 확인하기, String을 Enum으로 변환하기 (0) | 2022.07.29 |
[Unity] Renderer의 Materials 동적 변경 (0) | 2022.06.08 |
[Unity] JSON을 딕셔너리처럼 입출력하기 (0) | 2022.05.17 |
[Unity] Raycasthit.transform과 Raycasthit.collider.transform (0) | 2022.05.09 |