using UnityEngine; using System; public class PlayerHealth : MonoBehaviour, IDamageable { [SerializeField] private Stats stats; [SerializeField] private Animator animator; public bool IsDead { get; private set; } public bool isHit { get; private set; } public event Action OnHit, OnDead; public event Action OnHealthChanged; private float _currentHealth; private void Start() { if (stats != null) { _currentHealth = stats.MaxHealth; OnHealthChanged?.Invoke(_currentHealth, stats.MaxHealth); } if (animator == null) animator = GetComponent(); } // ⭐ [최종 수정] 최대 체력 변동 시 호출: 피는 안 채우되, 그릇(MaxHealth)을 넘치는 피는 깎습니다. public void RefreshHealthUI() { if (stats != null) { // 1. [핵심] 현재 체력이 최대 체력을 넘지 못하도록 고정 (Clamp) // 최대 체력이 늘어나면 기존 피 유지, 줄어들어서 피가 넘치면 최대치로 깎음 _currentHealth = Mathf.Min(_currentHealth, stats.MaxHealth); // 2. 즉시 UI에 바뀐 수치를 보냅니다. if (OnHealthChanged != null) { OnHealthChanged.Invoke(_currentHealth, stats.MaxHealth); Debug.Log($"[Health Sync] UI 갱신 완료: {_currentHealth} / {stats.MaxHealth}"); } } } // ... (TakeDamage 등 나머지 기존 코드 유지) public void TakeDamage(float amount) { if (IsDead) return; _currentHealth = Mathf.Max(0, _currentHealth - amount); OnHealthChanged?.Invoke(_currentHealth, stats.MaxHealth); OnHit?.Invoke(); if (!IsDead) StartHit(); if (_currentHealth <= 0) Die(); } private void StartHit() { isHit = true; if (animator != null) animator.Play("HitAnime", 0, 0f); CancelInvoke(nameof(OnHitEnd)); Invoke(nameof(OnHitEnd), 0.05f); } public void OnHitEnd() { isHit = false; } private void Die() { IsDead = true; Cursor.visible = true; Cursor.lockState = CursorLockMode.None; OnDead?.Invoke(); } public void Heal(float amount) { if (IsDead) return; // 현재 체력에 회복량을 더하되, Stats의 MaxHealth를 넘지 못하게 합니다. _currentHealth = Mathf.Min(_currentHealth + amount, stats.MaxHealth); // UI 갱신 OnHealthChanged?.Invoke(_currentHealth, stats.MaxHealth); } }