Files
Alex38Lyon 878ea46cac update
2025-06-03 12:00:47 +02:00

87 lines
2.3 KiB
C#

using UnityEngine;
using UnityEngine.Events;
namespace Unity.FPS.Game
{
public class Health : MonoBehaviour
{
[Tooltip("Maximum amount of health")] public float MaxHealth = 10f;
[Tooltip("Health ratio at which the critical health vignette starts appearing")]
public float CriticalHealthRatio = 0.3f;
public UnityAction<float, GameObject> OnDamaged;
public UnityAction<float> OnHealed;
public UnityAction OnDie;
public float CurrentHealth { get; set; }
public bool Invincible { get; set; }
public bool CanPickup() => CurrentHealth < MaxHealth;
public float GetRatio() => CurrentHealth / MaxHealth;
public bool IsCritical() => GetRatio() <= CriticalHealthRatio;
bool m_IsDead;
void Start()
{
CurrentHealth = MaxHealth;
}
public void Heal(float healAmount)
{
float healthBefore = CurrentHealth;
CurrentHealth += healAmount;
CurrentHealth = Mathf.Clamp(CurrentHealth, 0f, MaxHealth);
// call OnHeal action
float trueHealAmount = CurrentHealth - healthBefore;
if (trueHealAmount > 0f)
{
OnHealed?.Invoke(trueHealAmount);
}
}
public void TakeDamage(float damage, GameObject damageSource)
{
if (Invincible)
return;
float healthBefore = CurrentHealth;
CurrentHealth -= damage;
CurrentHealth = Mathf.Clamp(CurrentHealth, 0f, MaxHealth);
// call OnDamage action
float trueDamageAmount = healthBefore - CurrentHealth;
if (trueDamageAmount > 0f)
{
OnDamaged?.Invoke(trueDamageAmount, damageSource);
}
HandleDeath();
}
public void Kill()
{
CurrentHealth = 0f;
// call OnDamage action
OnDamaged?.Invoke(MaxHealth, null);
HandleDeath();
}
void HandleDeath()
{
if (m_IsDead)
return;
// call OnDie action
if (CurrentHealth <= 0f)
{
m_IsDead = true;
OnDie?.Invoke();
}
}
}
}