using UnityEngine;
using UnityEngine.Events;
namespace UnityAgent
{
///
/// Damageable entity with health regen and death event. Pairs with the
/// optional UI component.
///
public class HealthSystem : MonoBehaviour
{
[Header("Health")]
public float maxHealth = 100f;
public float currentHealth { get; private set; }
public float regenPerSecond = 1f;
public float regenDelay = 5f;
[Header("Events")]
public UnityEvent onDeath;
public UnityEvent onDamaged;
private float _lastDamageTime;
private bool _dead;
public float Normalised => currentHealth / maxHealth;
private void Awake()
{
currentHealth = maxHealth;
}
private void Update()
{
if (_dead) return;
if (Time.time - _lastDamageTime > regenDelay && currentHealth < maxHealth)
{
currentHealth = Mathf.Min(maxHealth, currentHealth + regenPerSecond * Time.deltaTime);
}
}
public void TakeDamage(float amount)
{
if (_dead) return;
currentHealth = Mathf.Max(0f, currentHealth - amount);
_lastDamageTime = Time.time;
onDamaged?.Invoke(amount);
if (currentHealth <= 0f) Die();
}
public void Heal(float amount)
{
if (_dead) return;
currentHealth = Mathf.Min(maxHealth, currentHealth + amount);
}
private void Die()
{
_dead = true;
onDeath?.Invoke();
Destroy(gameObject, 0.5f);
}
}
///
/// Simple health bar that reads a and updates
/// a child Image.fillAmount.
///
public class HealthBar : MonoBehaviour
{
public HealthSystem source;
public UnityEngine.UI.Image fillImage;
public bool hideWhenFull = true;
private void Update()
{
if (source == null || fillImage == null) return;
float n = source.Normalised;
fillImage.fillAmount = n;
if (hideWhenFull) fillImage.transform.parent.gameObject.SetActive(n < 0.999f);
}
}
}