65 lines
2.3 KiB
C#
65 lines
2.3 KiB
C#
using System;
|
|
using UnityEngine;
|
|
|
|
public class Health : MonoBehaviour
|
|
{
|
|
[SerializeField] private int _maxHealth = 30;
|
|
private int _currentHealth;
|
|
|
|
// ─── 읽기 전용 프로퍼티 ──────────────────────────────────────────────
|
|
public int MaxHealth => _maxHealth;
|
|
public int CurrentHealth => _currentHealth;
|
|
public float Ratio => _maxHealth > 0 ? (float)_currentHealth / _maxHealth : 0f;
|
|
public bool IsDead => _currentHealth <= 0;
|
|
|
|
// ─── 외부 구독용 이벤트 ──────────────────────────────────────────────
|
|
// OnHealthChanged: (current, max). 데미지 숫자 표시 등에 사용.
|
|
// OnDied: 사망 순간 1회만 발화.
|
|
public event Action<int, int> OnHealthChanged;
|
|
public event Action OnDied;
|
|
|
|
private void Awake()
|
|
{
|
|
_currentHealth = _maxHealth;
|
|
}
|
|
|
|
// 데미지 적용. 양수 데미지만 받고, 이미 죽었으면 무시.
|
|
// OnDied는 "방금 죽은 순간"에만 발화 (previous > 0 && current == 0).
|
|
public void TakeDamage(int amount)
|
|
{
|
|
if (amount <= 0 || IsDead) return;
|
|
|
|
int previous = _currentHealth;
|
|
_currentHealth = Mathf.Max(_currentHealth - amount, 0);
|
|
OnHealthChanged?.Invoke(_currentHealth, _maxHealth);
|
|
|
|
if (_currentHealth <= 0 && previous > 0)
|
|
OnDied?.Invoke();
|
|
}
|
|
|
|
// 회복
|
|
public void Heal(int amount)
|
|
{
|
|
if (amount <= 0 || IsDead) return;
|
|
|
|
_currentHealth = Mathf.Min(_currentHealth + amount, _maxHealth);
|
|
OnHealthChanged?.Invoke(_currentHealth, _maxHealth);
|
|
}
|
|
|
|
// 풀체력으로 리셋. 부활/재시작 시 사용.
|
|
public void ResetHealth()
|
|
{
|
|
_currentHealth = _maxHealth;
|
|
OnHealthChanged?.Invoke(_currentHealth, _maxHealth);
|
|
}
|
|
|
|
// 최대 HP 변경. fill=true면 현재 HP도 풀로 채우고, false면 새 max로 클램프만.
|
|
public void SetMaxHealth(int newMax, bool fill = true)
|
|
{
|
|
_maxHealth = Mathf.Max(newMax, 1);
|
|
if (fill) _currentHealth = _maxHealth;
|
|
else _currentHealth = Mathf.Min(_currentHealth, _maxHealth);
|
|
OnHealthChanged?.Invoke(_currentHealth, _maxHealth);
|
|
}
|
|
}
|