using UnityEngine; using UnityEngine.AI; public class NormalMonster : MonsterClass { [Header("전투 설정")] // ❌ private float damage 삭제됨 (부모의 attackDamage 사용) [SerializeField] private float attackRange = 2f; [SerializeField] private float attackDelay = 1.5f; private float lastAttackTime; [Header("공격 / 이동 애니메이션")] [SerializeField] private string[] attackAnimations = { "Monster_Attack_1" }; [SerializeField] private string Monster_Walk = "Monster_Walk"; [Header("AI 상세 설정")] [SerializeField] private float stopBuffer = 0.3f; [SerializeField] private float patrolRadius = 5f; [SerializeField] private float patrolInterval = 2f; private float nextPatrolTime; private float repathInterval = 0.3f; private float nextRepathTime; private int attackIndex; private bool isPlayerInZone; protected override void Init() { if (agent != null) agent.stoppingDistance = attackRange - 0.4f; if (animator != null) animator.applyRootMotion = false; } protected override void ExecuteAILogic() { if (isHit || isAttacking || isResting) return; float distance = Vector3.Distance(transform.position, playerTransform.position); if (isPlayerInZone || distance <= attackRange * 2f) HandlePlayerTarget(); else Patrol(); UpdateMovementAnimation(); } void HandlePlayerTarget() { float distance = Vector3.Distance(transform.position, playerTransform.position); if (distance <= attackRange - stopBuffer) TryAttack(); else if (Time.time >= nextRepathTime) { if (agent.isOnNavMesh) agent.SetDestination(playerTransform.position); nextRepathTime = Time.time + repathInterval; } } void TryAttack() { if (Time.time < lastAttackTime + attackDelay) return; lastAttackTime = Time.time; string attackName = attackAnimations[attackIndex]; attackIndex = (attackIndex + 1) % attackAnimations.Length; OnAttackStart(); animator.Play(attackName, 0, 0f); } // ⭐ [수정] 부모 클래스(MonsterClass)의 attackDamage를 플레이어에게 입힙니다. public void OnAttackHit() { if (playerTransform == null || isHit || isDead) return; if (playerTransform.TryGetComponent(out var pHealth)) { pHealth.TakeDamage(attackDamage); // ⭐ 부모의 변수 사용 Debug.Log($"[전투] {gameObject.name}이 {attackDamage} 데미지를 주었습니다!"); } } void UpdateMovementAnimation() { if (isAttacking || isHit || isResting) return; if (agent.velocity.magnitude < 0.1f) animator.Play(Monster_Idle); else animator.Play(Monster_Walk); } void Patrol() { if (Time.time < nextPatrolTime) return; Vector3 randomPoint = transform.position + new Vector3(Random.Range(-patrolRadius, patrolRadius), 0, Random.Range(-patrolRadius, patrolRadius)); if (NavMesh.SamplePosition(randomPoint, out NavMeshHit hit, 3f, NavMesh.AllAreas)) if (agent.isOnNavMesh) agent.SetDestination(hit.position); nextPatrolTime = Time.time + patrolInterval; } private void OnTriggerEnter(Collider other) { if (other.CompareTag("Player")) isPlayerInZone = true; } private void OnTriggerExit(Collider other) { if (other.CompareTag("Player")) isPlayerInZone = false; } }