Skip to content

Instantly share code, notes, and snippets.

@sbtoonz
Last active June 26, 2022 13:22
Show Gist options
  • Save sbtoonz/597cc369a29a86b00f817e31008fcf16 to your computer and use it in GitHub Desktop.
Save sbtoonz/597cc369a29a86b00f817e31008fcf16 to your computer and use it in GitHub Desktop.
Hit and hurtbox scripts for Unity
using Sirenix.OdinInspector;
using UnityEngine;
namespace Closure.Hit_Hurtbox
{
public class Hitbox : MonoBehaviour, IHitDetector
{
[SerializeField] private BoxCollider m_collider;
[SerializeField] private LayerMask m_layerMask;
[SerializeField] private float m_thickness = 0.025f;
private IHitResponder m_hitResponder;
public IHitResponder HitResponder { get=>m_hitResponder; set => m_hitResponder = value; }
public void CheckHit()
{
Vector3 scaledSize = new Vector3(
m_collider.size.x * transform.lossyScale.x,
m_collider.size.y * transform.lossyScale.y,
m_collider.size.z * transform.lossyScale.z
);
float distance = scaledSize.y = m_thickness;
Vector3 direction = transform.up;
Vector3 center = transform.TransformPoint(m_collider.center);
Vector3 start = center - direction * (distance / 2);
Vector3 halfextents = new Vector3(scaledSize.x, m_thickness, scaledSize.z) / 2;
Quaternion orientaion = transform.rotation;
HitData hitData;
IHurtbox _hurtbox;
RaycastHit[] hits = Physics.BoxCastAll(center, halfextents, direction, orientaion, distance, m_layerMask);
if (hits.Length <= 0)
{
//Debug.LogError("Raycast is empty");
return;
}
foreach (var hit in hits)
{
_hurtbox = hit.collider.GetComponent<IHurtbox>();
if (_hurtbox != null)
{
if (_hurtbox.Active)
{
hitData = new HitData
{
damage = m_hitResponder == null ? 0 : m_hitResponder.Damage,
hitPoint = hit.point == Vector3.zero ? center : hit.point,
hitNormal = hit.normal,
hurtbox = _hurtbox,
hitDetector = this
};
if (hitData.Validate())
{
hitData.hitDetector.HitResponder?.Response(hitData);
hitData.hurtbox.HurtResponder?.Response(hitData);
}
}
}
}
}
}
}
using System;
using UnityEngine;
namespace Closure.Hit_Hurtbox {
[Serializable]
public class HitData
{
public int damage;
public Vector3 hitPoint;
public Vector3 hitNormal;
public IHurtbox hurtbox;
public IHitDetector hitDetector;
public bool Validate()
{
if(hurtbox != null)
if(hurtbox.CheckHit(this))
if (hurtbox.HurtResponder == null || hurtbox.HurtResponder.CheckHit(this))
return true;
return false;
}
}
public interface IHitResponder
{
int Damage { get; }
public bool CheckHit(HitData data);
public void Response(HitData data);
}
public interface IHitDetector
{
public IHitResponder HitResponder { get; set; }
public void CheckHit();
}
public interface IHurtResponder
{
public bool CheckHit(HitData data);
public void Response(HitData data);
}
public interface IHurtbox
{
public bool Active { get; }
public GameObject Owner { get; }
public Transform Transform { get; }
public IHurtResponder HurtResponder { get; set; }
public bool CheckHit(HitData data);
}
}
using UnityEngine;
namespace Closure.Hit_Hurtbox
{
public class HitResponder: MonoBehaviour, IHitResponder
{
[SerializeField] internal bool m_attack;
[SerializeField] internal int m_damage = 10;
[SerializeField] internal Hitbox _hitbox;
public int Damage { get => m_damage; }
private void Start()
{
_hitbox.HitResponder = this;
}
private void Update()
{
if (m_attack)
{
_hitbox.CheckHit();
}
}
public bool CheckHit(HitData data)
{
if (data.hurtbox.Owner == gameObject)
{
return false;
}
else return true;
}
public void Response(HitData data)
{
}
}
}
using UnityEngine;
namespace Closure.Hit_Hurtbox
{
public interface ITargetable
{
public bool Targetable { get; }
public Transform TargetTransform { get; }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment