Part of these game systems:
Health System
Reusable health component with damage, healing, invincibility frames, and events.
How to Use
1
Attach to any GameObject that needs health (player, enemies, destructibles)
2
Configure max health and invincibility duration
3
Hook up events in the inspector or via code
4
Call TakeDamage() and Heal() from other scripts
Source Code
C#
using UnityEngine;
using UnityEngine.Events;
public class HealthSystem : MonoBehaviour
{
[Header("Health")]
[SerializeField] private float maxHealth = 100f;
[SerializeField] private float currentHealth;
[Header("Invincibility")]
[SerializeField] private float invincibilityDuration = 0.5f;
private float invincibilityTimer;
[Header("Events")]
public UnityEvent<float, float> OnHealthChanged; // current, max
public UnityEvent OnDeath;
public UnityEvent OnDamaged;
public UnityEvent OnHealed;
public float CurrentHealth => currentHealth;
public float MaxHealth => maxHealth;
public float HealthPercent => currentHealth / maxHealth;
public bool IsAlive => currentHealth > 0f;
public bool IsInvincible => invincibilityTimer > 0f;
private void Awake()
{
currentHealth = maxHealth;
}
private void Update()
{
if (invincibilityTimer > 0f)
invincibilityTimer -= Time.deltaTime;
}
public void TakeDamage(float damage)
{
if (!IsAlive || IsInvincible || damage <= 0f) return;
currentHealth = Mathf.Max(0f, currentHealth - damage);
invincibilityTimer = invincibilityDuration;
OnHealthChanged?.Invoke(currentHealth, maxHealth);
OnDamaged?.Invoke();
if (!IsAlive)
OnDeath?.Invoke();
}
public void Heal(float amount)
{
if (!IsAlive || amount <= 0f) return;
currentHealth = Mathf.Min(maxHealth, currentHealth + amount);
OnHealthChanged?.Invoke(currentHealth, maxHealth);
OnHealed?.Invoke();
}
public void SetMaxHealth(float newMax, bool healToFull = false)
{
maxHealth = newMax;
if (healToFull)
currentHealth = maxHealth;
else
currentHealth = Mathf.Min(currentHealth, maxHealth);
OnHealthChanged?.Invoke(currentHealth, maxHealth);
}
public void ResetHealth()
{
currentHealth = maxHealth;
invincibilityTimer = 0f;
OnHealthChanged?.Invoke(currentHealth, maxHealth);
}
}