Projext/Assets/Scripts/Enemy/AI/ChargeMonster.cs

80 lines
5.0 KiB
C#
Raw Normal View History

2026-02-13 09:11:54 +00:00
using UnityEngine; // 유니티 기능을 불러올거에요 -> UnityEngine을
using System.Collections; // 코루틴을 사용할거에요 -> System.Collections를
using System.Collections.Generic; // 리스트를 사용할거에요 -> System.Collections.Generic을
2026-02-04 14:06:25 +00:00
2026-02-13 09:11:54 +00:00
public class ChargeMonster : MonsterClass // 클래스를 선언할거에요 -> 돌진 몬스터를
2026-02-04 14:06:25 +00:00
{
2026-02-13 09:11:54 +00:00
[Header("=== 돌진 설정 ===")] // 인스펙터 제목을 달거에요 -> 돌진 설정을
[SerializeField] private float chargeSpeed = 15f; // 변수를 선언할거에요 -> 속도를
[SerializeField] private float chargeRange = 10f; // 변수를 선언할거에요 -> 감지 거리를
[SerializeField] private float chargeDuration = 2f; // 변수를 선언할거에요 -> 지속 시간을
[SerializeField] private float chargeDelay = 3f; // 변수를 선언할거에요 -> 쿨타임을
[SerializeField] private float prepareTime = 0.5f; // 변수를 선언할거에요 -> 준비 시간을
[Header("애니메이션")] // 인스펙터 제목을 달거에요 -> 애니메이션을
[SerializeField] private string chargeAnim = "Monster_Charge"; // 변수를 선언할거에요 -> 돌진 애니를
[SerializeField] private string prepareAnim = "Monster_ChargePrepare"; // 변수를 선언할거에요 -> 준비 애니를
[SerializeField] private string walkAnim = "Monster_Walk"; // 변수를 선언할거에요 -> 걷기 애니를
private float lastChargeTime; // 변수를 선언할거에요 -> 마지막 돌진 시간을
private bool isCharging; // 변수를 선언할거에요 -> 돌진 중 여부를
private Rigidbody _rb; // 변수를 선언할거에요 -> 리지드바디를
protected override void Awake() // 함수를 실행할거에요 -> 초기화 Awake를
2026-02-04 14:06:25 +00:00
{
2026-02-13 09:11:54 +00:00
base.Awake(); // 부모 함수를 실행할거에요
_rb = GetComponent<Rigidbody>(); // 가져올거에요 -> 리지드바디를
if (_rb == null) _rb = gameObject.AddComponent<Rigidbody>(); // 추가할거에요 -> 없으면 새로
_rb.isKinematic = true; // 끌거에요 -> 물리 연산을
2026-02-04 14:06:25 +00:00
}
2026-02-13 09:11:54 +00:00
protected override void Init() { if (agent != null) agent.stoppingDistance = 1f; } // 초기화할거에요 -> 정지 거리를
2026-02-04 14:06:25 +00:00
2026-02-13 09:11:54 +00:00
protected override void ExecuteAILogic() // 함수를 실행할거에요 -> AI 로직을
2026-02-04 14:06:25 +00:00
{
2026-02-13 09:11:54 +00:00
if (isHit || isCharging || isAttacking) return; // 중단할거에요 -> 행동 불가면
float dist = Vector3.Distance(transform.position, playerTransform.position); // 계산할거에요 -> 거리를
if (dist <= chargeRange && Time.time >= lastChargeTime + chargeDelay) StartCoroutine(ChargeRoutine()); // 실행할거에요 -> 돌진을
else ChasePlayer(); // 실행할거에요 -> 추격을
2026-02-04 14:06:25 +00:00
}
2026-02-13 09:11:54 +00:00
private void ChasePlayer() // 함수를 선언할거에요 -> 추격 로직을
2026-02-04 14:06:25 +00:00
{
2026-02-13 09:11:54 +00:00
if (agent.isOnNavMesh) { agent.isStopped = false; agent.SetDestination(playerTransform.position); } // 이동할거에요 -> 플레이어에게
animator.Play(walkAnim); // 재생할거에요 -> 걷기 애니를
2026-02-04 14:06:25 +00:00
}
2026-02-13 09:11:54 +00:00
private IEnumerator ChargeRoutine() // 코루틴 함수를 정의할거에요 -> 돌진 과정을
2026-02-04 14:06:25 +00:00
{
2026-02-13 09:11:54 +00:00
isAttacking = true; agent.isStopped = true; // 설정할거에요 -> 공격 상태와 정지를
animator.Play(prepareAnim); // 재생할거에요 -> 준비 애니를
2026-02-04 14:06:25 +00:00
2026-02-13 09:11:54 +00:00
Vector3 dir = (playerTransform.position - transform.position).normalized; dir.y = 0; // 계산할거에요 -> 방향을
transform.rotation = Quaternion.LookRotation(dir); // 회전할거에요 -> 방향대로
2026-02-12 15:23:25 +00:00
yield return new WaitForSeconds(prepareTime); // 기다릴거에요 -> 준비 시간만큼
2026-02-04 14:06:25 +00:00
2026-02-13 09:11:54 +00:00
isCharging = true; lastChargeTime = Time.time; // 설정할거에요 -> 돌진 상태와 시간을
agent.enabled = false; _rb.isKinematic = false; // 전환할거에요 -> 물리 이동으로
animator.Play(chargeAnim); // 재생할거에요 -> 돌진 애니를
2026-02-05 15:42:48 +00:00
2026-02-13 09:11:54 +00:00
float elapsed = 0f; // 초기화할거에요 -> 경과 시간을
while (elapsed < chargeDuration) // 반복할거에요 -> 지속 시간 동안
2026-02-04 14:06:25 +00:00
{
2026-02-13 09:11:54 +00:00
_rb.velocity = transform.forward * chargeSpeed; // 적용할거에요 -> 속도를
elapsed += Time.deltaTime; // 더할거에요 -> 시간을
2026-02-12 15:23:25 +00:00
yield return null; // 대기할거에요 -> 다음 프레임까지
2026-02-04 14:06:25 +00:00
}
2026-02-13 09:11:54 +00:00
_rb.velocity = Vector3.zero; _rb.isKinematic = true; agent.enabled = true; // 복구할거에요 -> 상태를
isCharging = false; OnAttackEnd(); // 종료할거에요 -> 돌진과 공격을
2026-02-04 14:06:25 +00:00
}
2026-02-13 09:11:54 +00:00
private void OnCollisionEnter(Collision col) // 함수를 실행할거에요 -> 충돌 시
2026-02-04 14:06:25 +00:00
{
2026-02-13 09:11:54 +00:00
if (isCharging && col.gameObject.CompareTag("Player")) // 조건이 맞으면 실행할거에요 -> 돌진 중 플레이어 충돌이면
2026-02-06 09:27:08 +00:00
{
2026-02-13 09:11:54 +00:00
var t = col.gameObject.GetComponent<IDamageable>(); // 가져올거에요 -> 인터페이스를
if (t != null) t.TakeDamage(attackDamage); // 입힐거에요 -> 데미지를
2026-02-04 14:06:25 +00:00
}
}
2026-02-05 15:42:48 +00:00
}