using UnityEngine; // 유니티 기능을 불러올거에요 -> UnityEngine을 // ============================================================ // NorcielBoss.PublicAPI.cs — 외부 컴포넌트용 읽기전용 API (partial class) // // [역할] // BossDebugDisplay 등 외부 컴포넌트가 보스 상태를 안전하게 읽을 수 있도록 // public getter 메서드와 프로퍼티를 한 곳에 모아둡니다. // // [설계] // partial class로 NorcielBoss의 private 필드에 직접 접근합니다. // 모든 API는 읽기전용이며 상태를 변경하지 않습니다. (테스트 메서드 제외) // ============================================================ public partial class NorcielBoss : MonsterClass // 부분 클래스를 선언할거에요 -> NorcielBoss의 Public API 부분으로 { // ══════════════════════════════════════════════════════════ // Phase 상태 (읽기전용 프로퍼티) // ══════════════════════════════════════════════════════════ /// Phase2 진입 여부 — phaseManager에서 가져옴 public bool IsPhase2 => phaseManager != null && phaseManager.IsPhase2; // 속성을 선언할거에요 -> Phase2 여부를 (외부 접근용) /// Phase3 진입 여부 — phaseManager에서 가져옴 public bool IsPhase3 => phaseManager != null && phaseManager.IsPhase3; // 속성을 선언할거에요 -> Phase3 여부를 (외부 접근용) /// 전투 시작 여부 public bool IsBattleStarted => _isBattleStarted; // 속성을 선언할거에요 -> 전투 시작 여부를 (외부 접근용) // ══════════════════════════════════════════════════════════ // FSM 상태 조회 // ══════════════════════════════════════════════════════════ /// 현재 FSM 상태 반환 public BossState GetCurrentState() => _state; // 함수를 선언할거에요 -> 현재 FSM 상태를 반환하는 // ══════════════════════════════════════════════════════════ // 거리/범위 파라미터 조회 (Inspector 설정값 읽기) // ══════════════════════════════════════════════════════════ /// 근접 사거리 (m) public float GetMeleeRange() => meleeRange; // 함수를 선언할거에요 -> 근접 사거리를 반환하는 /// 던지기 사거리 (m) public float GetThrowRange() => throwRange; // 함수를 선언할거에요 -> 던지기 사거리를 반환하는 /// 대시 발동 거리 (m) public float GetDashChaseRange() => dashChaseRange; // 함수를 선언할거에요 -> 대시 발동 거리를 반환하는 /// [v6.5] 대시 쿨다운 시간 (초) — ChargeMonster의 chargeDelay 역할 public float GetDashCooldownTime() => dashCooldownTime; // 함수를 선언할거에요 -> 대시 쿨다운 시간을 반환하는 /// 내려찍기 판정 중심 오프셋 (보스 앞방향 m) public float GetSmashForwardOffset() => smashForwardOffset; // 함수를 선언할거에요 -> 스매시 오프셋을 반환하는 /// 내려찍기 판정 반경 (m) public float GetSmashRadius() => smashRadius; // 함수를 선언할거에요 -> 스매시 반경을 반환하는 /// 휩쓸기 판정 반경 (m) public float GetSweepRadius() => sweepRadius; // 함수를 선언할거에요 -> 휩쓸기 반경을 반환하는 /// 대시+스매시 콤보 대시 중단 거리 (m) public float GetDashSmashArriveRange() => dashSmashArriveRange; // 함수를 선언할거에요 -> 콤보 도착 거리를 반환하는 // ══════════════════════════════════════════════════════════ // 전투 상태 조회 // ══════════════════════════════════════════════════════════ /// 현재 콤보 카운터 (연속 공격 횟수) public int GetComboCounter() => _comboCounter; // 함수를 선언할거에요 -> 콤보 카운터를 반환하는 /// 최대 콤보 횟수 — phaseManager에서 가져옴 public int GetMaxComboCount() => (phaseManager != null) ? phaseManager.MaxComboCount : 3; // 함수를 선언할거에요 -> 최대 콤보 횟수를 반환하는 /// 공격 쿨타임 남은 시간 (초) public float GetAttackTimer() => _attackTimer; // 함수를 선언할거에요 -> 공격 쿨타임을 반환하는 /// 공격 패턴 간격 (초) public float GetPatternInterval() => patternInterval; // 함수를 선언할거에요 -> 패턴 간격을 반환하는 /// 플레이어까지 거리 (m) — 타겟 없으면 9999 public float GetDistanceToTarget() => GetDist(); // 함수를 선언할거에요 -> 플레이어까지 거리를 반환하는 // ══════════════════════════════════════════════════════════ // HP 조회 (MonsterClass 필드 래핑) // ══════════════════════════════════════════════════════════ /// 최대 HP public float GetMaxHP() => maxHP; // 함수를 선언할거에요 -> 최대 HP를 반환하는 /// 현재 HP public float GetCurrentHP() => currentHP; // 함수를 선언할거에요 -> 현재 HP를 반환하는 // ══════════════════════════════════════════════════════════ // 디버그용 텍스트 조회 // ══════════════════════════════════════════════════════════ /// 직전 사용 패턴 텍스트 (연속 횟수 포함) public string GetLastPatternText() // 함수를 선언할거에요 -> 직전 패턴 정보를 텍스트로 반환하는 { if ((int)_lastPattern < 0) return "없음"; // 반환할거에요 -> 아직 패턴 사용 전이면 "없음"을 string name = _lastPattern.ToString(); // 변환할거에요 -> 패턴 이름을 문자열로 if (_samePatternCount > 1) // 조건이 맞으면 실행할거에요 -> 연속 사용이면 name += $" x{_samePatternCount}"; // 덧붙일거에요 -> 연속 횟수를 return name; // 반환할거에요 -> 패턴 텍스트를 } /// 플레이어 행동 감지 상태 텍스트 (정지/접근/도주/카이팅) public string GetPlayerBehaviorText() // 함수를 선언할거에요 -> 플레이어 행동 감지 정보를 텍스트로 반환하는 { string text = ""; // 초기화할거에요 -> 빈 텍스트로 if (_playerStillTimer >= stillPunishTime) // 조건이 맞으면 실행할거에요 -> 정지 감지됐으면 text += $"[정지 {_playerStillTimer:F1}s] "; // 덧붙일거에요 -> 정지 경고를 if (_playerApproachTimer >= approachReactTime) // 조건이 맞으면 실행할거에요 -> 접근 감지됐으면 text += $"[접근 {_playerApproachTimer:F1}s] "; // 덧붙일거에요 -> 접근 감지를 if (_playerFleeTimer >= 1f) // 조건이 맞으면 실행할거에요 -> 도주 감지됐으면 text += $"[도주 {_playerFleeTimer:F1}s] "; // 덧붙일거에요 -> 도주 감지를 if (_kitingTimer >= kitingDetectTime * 0.5f) // 조건이 맞으면 실행할거에요 -> 카이팅 감지 중이면 text += $"[카이팅 {_kitingTimer:F1}s]"; // 덧붙일거에요 -> 카이팅 감지를 return text; // 반환할거에요 -> 완성된 텍스트를 } // ══════════════════════════════════════════════════════════ // 디버그/테스트용 제어 메서드 // ══════════════════════════════════════════════════════════ /// Inspector 테스트 버튼에서 호출 — 지정 패턴을 강제 실행 public void TestStartPattern(string patternName) // 함수를 선언할거에요 -> 테스트용 패턴 강제 실행을 { if (_state == BossState.Dead) return; // 중단할거에요 -> 사망 상태면 // 문자열을 BossPattern으로 파싱 if (System.Enum.TryParse(patternName, out BossPattern pattern)) // 파싱할거에요 -> 문자열을 패턴 열거형으로 { Debug.Log($"[Boss Test] 패턴 강제 실행: {pattern}"); // 로그를 찍을거에요 StartPattern(pattern); // 시작할거에요 -> 해당 패턴을 } else // 아니면 { Debug.LogWarning($"[Boss Test] 알 수 없는 패턴 이름: {patternName}"); // 경고를 찍을거에요 } } // ══════════════════════════════════════════════════════════ // 전투 시작 — BossZoneTrigger에서 호출 // ══════════════════════════════════════════════════════════ /// 보스전 시작 — 포효 연출 후 Chase 상태로 전환 (BossZoneTrigger에서 호출) public void StartBossBattle() // 함수를 선언할거에요 -> 보스전을 시작하는 (외부 호출용) { if (_isBattleStarted) return; // 중단할거에요 -> 이미 시작됐으면 중복 방지 StartCoroutine(BattleStartRoutine()); // 시작할거에요 -> 전투 시작 코루틴을 } /// 전투 시작 코루틴 — 포효 애니 → 체력바 표시 → Chase 전환 private System.Collections.IEnumerator BattleStartRoutine() // 코루틴을 정의할거에요 -> 전투 시작 연출을 처리하는 { _isBattleStarted = true; // 설정할거에요 -> 전투 시작 플래그를 // NavMesh 에이전트 활성화 if (agent != null) agent.enabled = true; // 켤거에요 -> 에이전트를 (Init에서 꺼뒀으므로) // 체력바 표시 if (bossHealthBar != null) bossHealthBar.SetActive(true); // 켤거에요 -> 체력바를 // 포효 애니메이션 재생 + 대기 PlayAnimDirect(anim_Roar); // 재생할거에요 -> 포효 애니를 yield return new UnityEngine.WaitForSeconds(2f); // 기다릴거에요 -> 포효 시간을 (애니 종료 대기) // FSM 가동 → Chase 상태로 전환 SetState(BossState.Chase); // 전환할거에요 -> 추격 상태로 _attackTimer = patternInterval * 0.5f; // 설정할거에요 -> 첫 공격 쿨타임을 (v6: 절반으로 단축 → 포효 후 빠르게 첫 패턴 발동) Debug.Log("[Boss] 전투 시작! → Chase 상태 진입"); // 로그를 찍을거에요 } /// Inspector 테스트 버튼에서 호출 — Phase2 강제 진입 public void TestEnterPhase2() // 함수를 선언할거에요 -> 테스트용 Phase2 강제 진입을 { if (phaseManager != null) // 조건이 맞으면 실행할거에요 -> phaseManager 있으면 { Debug.Log("[Boss Test] Phase2 강제 진입!"); // 로그를 찍을거에요 phaseManager.ConfirmPhase2(); // 호출할거에요 -> Phase2 강제 진입을 OnPhaseChanged(2); // 실행할거에요 -> Phase 전환 연출을 } } }