using UnityEngine; // 유니티 기능을 불러올거에요 -> UnityEngine을 using System.Collections; // 코루틴을 사용할거에요 -> System.Collections를 public class ExplodeMonster : MonsterClass // 클래스를 선언할거에요 -> 자폭 몬스터를 { [Header("=== 자폭 설정 ===")] // 인스펙터 제목을 달거에요 -> 자폭 설정을 [SerializeField] private float explodeRange = 4f; // 변수를 선언할거에요 -> 폭발 범위를 [SerializeField] private float triggerRange = 2.5f; // 변수를 선언할거에요 -> 감지 범위를 [SerializeField] private float fuseTime = 1.5f; // 변수를 선언할거에요 -> 지연 시간을 [SerializeField] private float explosionDamage = 50f; // 변수를 선언할거에요 -> 폭발 데미지를 [Header("이펙트")] // 인스펙터 제목을 달거에요 -> 이펙트를 [SerializeField] private GameObject explosionEffectPrefab; // 변수를 선언할거에요 -> 폭발 이펙트를 [SerializeField] private ParticleSystem fuseEffect; // 변수를 선언할거에요 -> 도화선 이펙트를 [SerializeField] private AudioClip fuseSound; // 변수를 선언할거에요 -> 도화선 소리를 [SerializeField] private AudioClip explosionSound; // 변수를 선언할거에요 -> 폭발 소리를 [Header("애니메이션")] // 인스펙터 제목을 달거에요 -> 애니메이션을 [SerializeField] private string runAnim = "Monster_Run"; // 변수를 선언할거에요 -> 달리기 애니 이름을 [SerializeField] private string fuseAnim = "Monster_Fuse"; // 변수를 선언할거에요 -> 점화 애니 이름을 private bool hasExploded = false; // 변수를 선언할거에요 -> 폭발 여부를 protected override void Init() // 함수를 실행할거에요 -> 초기화 Init을 { if (agent != null) agent.stoppingDistance = 0.5f; // 설정을 바꿀거에요 -> 정지 거리를 짧게 } protected override void ExecuteAILogic() // 함수를 실행할거에요 -> AI 로직을 { if (isHit || isAttacking || hasExploded) return; // 조건이 맞으면 중단할거에요 -> 행동 불가면 float dist = Vector3.Distance(transform.position, playerTransform.position); // 거리를 계산할거에요 -> 플레이어와의 if (dist <= triggerRange) // 조건이 맞으면 실행할거에요 -> 감지 거리 안이면 { StartCoroutine(ExplodeRoutine()); // 코루틴을 실행할거에요 -> 자폭 시퀀스를 } else // 조건이 틀리면 실행할거에요 -> 멀면 { ChasePlayer(); // 함수를 실행할거에요 -> 추격을 } } private void ChasePlayer() // 함수를 선언할거에요 -> 추격 로직을 { if (agent.isOnNavMesh) // 조건이 맞으면 실행할거에요 -> 내비게이션 위라면 { agent.isStopped = false; // 명령을 내릴거에요 -> 이동 재개 agent.SetDestination(playerTransform.position); // 명령을 내릴거에요 -> 플레이어 위치로 } animator.Play(runAnim); // 재생할거에요 -> 달리기 애니를 } private IEnumerator ExplodeRoutine() // 코루틴 함수를 정의할거에요 -> 자폭 과정을 { isAttacking = true; // 상태를 바꿀거에요 -> 공격 중으로 (이동 불가) hasExploded = true; // 상태를 바꿀거에요 -> 폭발 됨으로 (중복 방지) if (agent.isOnNavMesh) { agent.isStopped = true; agent.velocity = Vector3.zero; } // 명령을 내릴거에요 -> 정지 // 1. 점화 animator.Play(fuseAnim); // 재생할거에요 -> 점화 애니를 if (fuseEffect != null) fuseEffect.Play(); // 실행할거에요 -> 도화선 효과를 if (fuseSound != null) audioSource.PlayOneShot(fuseSound); // 재생할거에요 -> 도화선 소리를 yield return new WaitForSeconds(fuseTime); // 기다릴거에요 -> 지연 시간만큼 // 2. 폭발 Explode(); // 함수를 실행할거에요 -> 폭발 처리를 } private void Explode() // 함수를 선언할거에요 -> 실제 폭발 로직을 { if (explosionEffectPrefab != null) Instantiate(explosionEffectPrefab, transform.position, Quaternion.identity); // 생성할거에요 -> 폭발 이펙트를 if (explosionSound != null) AudioSource.PlayClipAtPoint(explosionSound, transform.position); // 재생할거에요 -> 폭발 소리를 // 범위 데미지 처리 Collider[] hits = Physics.OverlapSphere(transform.position, explodeRange); // 배열에 담을거에요 -> 범위 내 충돌체들을 foreach (var hit in hits) // 반복할거에요 -> 충돌체마다 { if (hit.CompareTag("Player")) // 조건이 맞으면 실행할거에요 -> 플레이어라면 { var hp = hit.GetComponent(); // 가져올거에요 -> 체력 인터페이스를 if (hp != null) hp.TakeDamage(explosionDamage); // 실행할거에요 -> 폭발 데미지 입히기를 } } // 자폭이므로 몬스터 사망 currentHP = 0; // 값을 설정할거에요 -> 체력을 0으로 Die(); // 실행할거에요 -> 사망 함수를 } protected override void OnStartHit() { } // 가상 함수를 비울거에요 -> 피격 되어도 멈추지 않게 (슈퍼아머) }