using UnityEngine; using System; using System.Collections; // ⭐ IEnumerator 사용을 위해 추가 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 bool isInvincible; // 대시 중 무적 플래그 public event Action OnHit, OnDead; public event Action OnHealthChanged; private float _currentHealth; // ⭐ [수정] Start를 코루틴으로 변경하여 실행 순서 문제를 해결합니다. private IEnumerator Start() { // 모든 오브젝트가 깨어날 때까지 한 프레임 기다립니다. yield return null; if (stats != null) { _currentHealth = stats.MaxHealth; // 이제 UI가 확실히 준비되었으므로 수치를 전달합니다. OnHealthChanged?.Invoke(_currentHealth, stats.MaxHealth); Debug.Log($"[UI Sync] 초기 체력 설정 완료: {_currentHealth}/{stats.MaxHealth}"); } if (animator == null) animator = GetComponent(); } public void RefreshHealthUI() { if (stats != null) { _currentHealth = Mathf.Min(_currentHealth, stats.MaxHealth); OnHealthChanged?.Invoke(_currentHealth, stats.MaxHealth); } } public void TakeDamage(float amount) { if (isInvincible || 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.25f); } 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; _currentHealth = Mathf.Min(_currentHealth + amount, stats.MaxHealth); OnHealthChanged?.Invoke(_currentHealth, stats.MaxHealth); } }