66 lines
1.8 KiB
C#
66 lines
1.8 KiB
C#
|
|
using System;
|
||
|
|
using UnityEngine;
|
||
|
|
|
||
|
|
namespace OTGIntegrated.Combat
|
||
|
|
{
|
||
|
|
public class Damageable : MonoBehaviour
|
||
|
|
{
|
||
|
|
public string displayName = "Target";
|
||
|
|
[Min(1f)] public float maxHealth = 50f;
|
||
|
|
[SerializeField] protected float currentHealth = 50f;
|
||
|
|
public Transform floatingDamageAnchor;
|
||
|
|
|
||
|
|
public event Action<float> OnDamageTaken;
|
||
|
|
public event Action OnDeath;
|
||
|
|
|
||
|
|
public float CurrentHealth => currentHealth;
|
||
|
|
public float MaxHealth => maxHealth;
|
||
|
|
public bool IsAlive => currentHealth > 0f;
|
||
|
|
|
||
|
|
protected virtual void Awake()
|
||
|
|
{
|
||
|
|
maxHealth = Mathf.Max(1f, maxHealth);
|
||
|
|
if (currentHealth <= 0f)
|
||
|
|
{
|
||
|
|
currentHealth = maxHealth;
|
||
|
|
}
|
||
|
|
|
||
|
|
currentHealth = Mathf.Clamp(currentHealth, 0f, maxHealth);
|
||
|
|
}
|
||
|
|
|
||
|
|
public virtual void TakeDamage(float amount, GameObject source = null)
|
||
|
|
{
|
||
|
|
if (!IsAlive || amount <= 0f)
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
currentHealth = Mathf.Clamp(currentHealth - amount, 0f, maxHealth);
|
||
|
|
OnDamageTaken?.Invoke(amount);
|
||
|
|
|
||
|
|
Vector3 anchor = floatingDamageAnchor != null ? floatingDamageAnchor.position : transform.position + Vector3.up * 1.6f;
|
||
|
|
FloatingDamage.Spawn(anchor, Mathf.RoundToInt(amount), new Color(1f, 0.46f, 0.24f, 1f));
|
||
|
|
|
||
|
|
if (currentHealth <= 0f)
|
||
|
|
{
|
||
|
|
HandleDeath(source);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public virtual void Heal(float amount)
|
||
|
|
{
|
||
|
|
if (amount <= 0f || !IsAlive)
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
currentHealth = Mathf.Clamp(currentHealth + amount, 0f, maxHealth);
|
||
|
|
}
|
||
|
|
|
||
|
|
protected virtual void HandleDeath(GameObject source)
|
||
|
|
{
|
||
|
|
OnDeath?.Invoke();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|