Projext/Assets/02_Scripts/Enemy/BossAI/NorcielBoss.Movement.cs

77 lines
5.0 KiB
C#
Raw Normal View History

using UnityEngine; // 유니티 기능을 불러올거에요 -> UnityEngine을
// ============================================================
// NorcielBoss.Movement.cs — NavMesh 에이전트 제어 + 회전/거리 유틸 (partial class)
//
// [역할]
// ① NavMesh 에이전트 시작/정지/상태 확인
// ② 타겟 방향 부드러운 회전 (FaceTarget)
// ③ 플레이어까지 거리 계산 (GetDist)
//
// [설계]
// partial class로 NorcielBoss의 agent, _target 등 필드에 직접 접근.
// FSM, 패턴 코루틴 등 여러 partial에서 공통으로 호출됩니다.
// ============================================================
public partial class NorcielBoss : MonsterClass // 부분 클래스를 선언할거에요 -> NorcielBoss의 이동 유틸 부분으로
{
// ══════════════════════════════════════════════════════════
// NavMesh 에이전트 제어
// ══════════════════════════════════════════════════════════
/// <summary>NavMesh 에이전트가 사용 가능한 상태인지 확인</summary>
private bool CheckNavMeshReady() // 함수를 선언할거에요 -> NavMesh 사용 가능한지 확인하는
{
return agent != null && agent.enabled && agent.isOnNavMesh; // 반환할거에요 -> 사용 가능 여부를
}
/// <summary>NavMesh 에이전트 활성화 + 이동 시작</summary>
private void StartAgent() // 함수를 선언할거에요 -> NavMesh 에이전트를 시작하는
{
if (agent == null) return; // 중단할거에요 -> 없으면
if (!agent.enabled) agent.enabled = true; // 켤거에요 -> 비활성이면
if (agent.isOnNavMesh) agent.isStopped = false; // 켤거에요 -> NavMesh 위면 이동 시작
}
/// <summary>NavMesh 에이전트 정지 + 관성 제거</summary>
private void StopAgent() // 함수를 선언할거에요 -> NavMesh 에이전트를 정지하는
{
if (!CheckNavMeshReady()) return; // 중단할거에요 -> 비정상이면
agent.isStopped = true; // 멈출거에요 -> 이동을
agent.velocity = Vector3.zero; // 제거할거에요 -> 관성을
}
// ══════════════════════════════════════════════════════════
// 회전 유틸리티
// ══════════════════════════════════════════════════════════
/// <summary>타겟(또는 지정 위치) 방향으로 회전 (Y축 고정)</summary>
/// <param name="overridePos">null이면 _target 위치 사용</param>
/// <param name="instant">true면 즉시 스냅 회전, false면 Slerp 부드러운 회전</param>
private void FaceTarget(Vector3? overridePos = null, bool instant = false) // 함수를 선언할거에요 -> 목표 방향으로 회전하는 (instant=true면 즉시 스냅)
{
Vector3 pos = overridePos ?? (_target != null ? _target.position : (Vector3?)null) ?? transform.position + transform.forward; // 결정할거에요 -> 바라볼 위치를
Vector3 dir = pos - transform.position; // 계산할거에요 -> 방향 벡터를
dir.y = 0f; // 제거할거에요 -> 높이 성분을 (수평 회전만)
if (dir.sqrMagnitude > 0.001f) // 조건이 맞으면 실행할거에요 -> 방향 있으면
{
Quaternion targetRot = Quaternion.LookRotation(dir); // 계산할거에요 -> 목표 회전을
if (instant) // 조건이 맞으면 실행할거에요 -> 즉시 스냅이면
transform.rotation = targetRot; // 스냅할거에요 -> 즉시 목표 방향으로 (1프레임에 완전 회전)
else // 조건이 틀리면 실행할거에요 -> 부드러운 회전이면
transform.rotation = Quaternion.Slerp(transform.rotation, targetRot, Time.deltaTime * 8f); // 회전할거에요 -> 부드럽게
}
}
// ══════════════════════════════════════════════════════════
// 거리 유틸리티
// ══════════════════════════════════════════════════════════
/// <summary>현재 타겟(플레이어)까지의 거리 반환 — 타겟 없으면 9999</summary>
private float GetDist() // 함수를 선언할거에요 -> 플레이어까지 거리를 반환하는
{
if (_target == null) return 9999f; // 반환할거에요 -> 타겟 없으면 최대값을
return Vector3.Distance(transform.position, _target.position); // 반환할거에요 -> 거리를
}
}