using UnityEngine; using UnityEngine.AI; using System; public class MonsterClass : MonoBehaviour, IDamageable { [Header("스탯")] [SerializeField] protected float maxHP = 100f; protected float currentHP; public event Action OnHealthChanged; [Header("피격 / 사망 애니메이션")] [SerializeField] protected string Monster_GetDamage = "Monster_GetDamage"; [SerializeField] protected string Monster_Die = "Monster_Die"; protected Animator animator; protected NavMeshAgent agent; protected AudioSource audioSource; protected bool isHit; protected bool isDead; [Header("경험치")] [SerializeField] protected int expReward = 10; public static System.Action OnMonsterKilled; [Header("공통 사운드/이펙트")] [SerializeField] protected AudioClip hitSound; [SerializeField] protected AudioClip deathSound; [SerializeField] protected GameObject deathEffectPrefab; [SerializeField] protected ParticleSystem hitEffect; [SerializeField] protected Transform impactSpawnPoint; protected virtual void Start() { currentHP = maxHP; animator = GetComponent(); agent = GetComponent(); audioSource = GetComponent(); OnHealthChanged?.Invoke(currentHP, maxHP); } // ⭐ 핵심: 부모에서 virtual을 붙여야 NormalMonster에서 에러가 안 납니다. public virtual void TakeDamage(float amount) { OnDamaged(amount); } public virtual void OnDamaged(float damage) { if (isDead) return; currentHP -= damage; Debug.Log($"{gameObject.name} 피격! 체력: {{{currentHP}/{maxHP}}}"); OnHealthChanged?.Invoke(currentHP, maxHP); if (currentHP <= 0) { Die(); return; } if (!isHit) StartHit(); } protected virtual void StartHit() { isHit = true; if (agent && agent.isOnNavMesh) { agent.isStopped = true; agent.velocity = Vector3.zero; } animator.Play(Monster_GetDamage, 0, 0f); if (hitEffect) hitEffect.Play(); if (hitSound) audioSource.PlayOneShot(hitSound); } public virtual void OnHitEnd() { isHit = false; if (agent && agent.isOnNavMesh) agent.isStopped = false; } protected virtual void Die() { if (isDead) return; isDead = true; // ⭐ 핵심 수정: 애니메이션 신호 기다리지 말고 즉시 처리 Debug.Log($"{gameObject.name} 사망! 경험치 {expReward} 지급 및 1.5초 후 파괴."); OnMonsterKilled?.Invoke(expReward); if (agent && agent.isOnNavMesh) { agent.isStopped = true; agent.velocity = Vector3.zero; } animator.Play(Monster_Die, 0, 0f); if (deathSound) audioSource.PlayOneShot(deathSound); // 1.5초 뒤 자동 삭제 (이벤트 씹힘 방지) Destroy(gameObject, 1.5f); } // 에러 방지용으로 남겨만 둠 public void OnDeathAnimEnd() { } }