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;
}
}
프로젝트 레포지토리
GitHub - qwes348/Unity_HitboxHurtbox: 유니티 히트박스, 허트박스 시스템 구현
유니티 히트박스, 허트박스 시스템 구현. Contribute to qwes348/Unity_HitboxHurtbox development by creating an account on GitHub.
github.com
구현에 참고한 문서
Hitboxes and Hurtboxes in Unity
What are Hitboxes and Hurtboxes? aren't they the same? and how do we implement them in Unity?
www.gamedeveloper.com
'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 |