207 lines
15 KiB
C#
207 lines
15 KiB
C#
|
|
using UnityEngine; // 유니티 기능을 불러올거에요 -> UnityEngine을
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// 보스 AI 디버그 표시 컴포넌트 — 씬 뷰 Gizmo + 게임 화면 OnGUI 디버그 정보 표시
|
||
|
|
/// 보스의 상태, 거리, 패턴, 카이팅 감지 등을 시각화해요.
|
||
|
|
/// </summary>
|
||
|
|
public class BossDebugDisplay : MonoBehaviour
|
||
|
|
{
|
||
|
|
// ══════════════════════════════════════════════════════════
|
||
|
|
// Inspector 연결
|
||
|
|
// ══════════════════════════════════════════════════════════
|
||
|
|
|
||
|
|
[Header("=== 보스 AI 참조 ===")]
|
||
|
|
[Tooltip("NorcielBoss 스크립트가 부착된 보스 오브젝트")] // 설명할거에요 -> 보스 참조 필드 설명을
|
||
|
|
[SerializeField] private NorcielBoss boss; // 변수를 선언할거에요 -> 보스 스크립트 참조를
|
||
|
|
|
||
|
|
// ══════════════════════════════════════════════════════════
|
||
|
|
// 패턴 테스트 버튼 (Inspector에서 플레이 중 체크)
|
||
|
|
// ══════════════════════════════════════════════════════════
|
||
|
|
|
||
|
|
[Header("=== 패턴 테스트 (플레이 중 Inspector에서 체크 → 즉시 실행) ===")]
|
||
|
|
[SerializeField] private bool testThrow = false; // 변수를 선언할거에요 -> 던지기 테스트 버튼을
|
||
|
|
|
||
|
|
[Header("=== Phase 테스트 ===")]
|
||
|
|
[SerializeField] private bool testPhase2 = false; // 변수를 선언할거에요 -> Phase2 강제 진입 버튼을
|
||
|
|
|
||
|
|
[Header("=== 근접 패턴 테스트 (플레이 중 Inspector에서 체크 → 즉시 실행) ===")]
|
||
|
|
[SerializeField] private bool testSmash = false; // 변수를 선언할거에요 -> 내려찍기 테스트 버튼을
|
||
|
|
[SerializeField] private bool testSweep = false; // 변수를 선언할거에요 -> 휩쓸기 테스트 버튼을
|
||
|
|
[SerializeField] private bool testDash = false; // 변수를 선언할거에요 -> 대시 테스트 버튼을
|
||
|
|
|
||
|
|
// ══════════════════════════════════════════════════════════
|
||
|
|
// 디버그 화면 로그 설정
|
||
|
|
// ══════════════════════════════════════════════════════════
|
||
|
|
|
||
|
|
[Header("=== 디버그 화면 로그 ===")]
|
||
|
|
[Tooltip("체크하면 게임 화면 좌측 상단에 보스 상태 로그를 표시해요")] // 설명할거에요 -> 화면 로그 표시 여부 설명을
|
||
|
|
[SerializeField] private bool debugLogOnScreen = true; // 변수를 선언할거에요 -> 화면 로그 표시 여부를
|
||
|
|
|
||
|
|
// ══════════════════════════════════════════════════════════
|
||
|
|
// Update — 테스트 버튼 폴링
|
||
|
|
// ══════════════════════════════════════════════════════════
|
||
|
|
|
||
|
|
private void Update() // 함수를 실행할거에요 -> 매 프레임을
|
||
|
|
{
|
||
|
|
if (boss == null) return; // 중단할거에요 -> 보스 참조 없으면
|
||
|
|
|
||
|
|
PollTestButtons(); // 확인할거에요 -> 테스트 버튼 입력을
|
||
|
|
}
|
||
|
|
|
||
|
|
// ══════════════════════════════════════════════════════════
|
||
|
|
// 테스트 버튼 폴링
|
||
|
|
// ══════════════════════════════════════════════════════════
|
||
|
|
|
||
|
|
private void PollTestButtons() // 함수를 선언할거에요 -> 매 프레임 Inspector 테스트 버튼을 확인하는
|
||
|
|
{
|
||
|
|
// 조건이 맞으면 실행할거에요 -> 던지기 테스트 체크됐으면
|
||
|
|
if (testThrow) // 조건을 확인할거에요 -> testThrow 플래그를
|
||
|
|
{
|
||
|
|
testThrow = false; // 초기화할거에요 -> 플래그를 (중복 발동 방지)
|
||
|
|
boss.TestStartPattern("Throw"); // 호출할거에요 -> 보스의 던지기 패턴 테스트를
|
||
|
|
}
|
||
|
|
|
||
|
|
// 조건이 맞으면 실행할거에요 -> Phase2 테스트 체크됐으면
|
||
|
|
if (testPhase2) // 조건을 확인할거에요 -> testPhase2 플래그를
|
||
|
|
{
|
||
|
|
testPhase2 = false; // 초기화할거에요 -> 플래그를 (중복 발동 방지)
|
||
|
|
boss.TestEnterPhase2(); // 호출할거에요 -> 보스의 Phase2 강제 진입을
|
||
|
|
}
|
||
|
|
|
||
|
|
// ─────────────── 근접 패턴 테스트 ─────────────────
|
||
|
|
// 조건이 맞으면 실행할거에요 -> 내려찍기 테스트 체크됐으면
|
||
|
|
if (testSmash) // 조건을 확인할거에요 -> testSmash 플래그를
|
||
|
|
{
|
||
|
|
testSmash = false; // 초기화할거에요 -> 플래그를 (중복 발동 방지)
|
||
|
|
boss.TestStartPattern("Smash"); // 호출할거에요 -> 보스의 내려찍기 패턴 테스트를
|
||
|
|
}
|
||
|
|
|
||
|
|
// 조건이 맞으면 실행할거에요 -> 휩쓸기 테스트 체크됐으면
|
||
|
|
if (testSweep) // 조건을 확인할거에요 -> testSweep 플래그를
|
||
|
|
{
|
||
|
|
testSweep = false; // 초기화할거에요 -> 플래그를 (중복 발동 방지)
|
||
|
|
boss.TestStartPattern("Sweep"); // 호출할거에요 -> 보스의 휩쓸기 패턴 테스트를
|
||
|
|
}
|
||
|
|
|
||
|
|
// 조건이 맞으면 실행할거에요 -> 대시 테스트 체크됐으면
|
||
|
|
if (testDash) // 조건을 확인할거에요 -> testDash 플래그를
|
||
|
|
{
|
||
|
|
testDash = false; // 초기화할거에요 -> 플래그를 (중복 발동 방지)
|
||
|
|
boss.TestStartPattern("Dash"); // 호출할거에요 -> 보스의 대시 추격 패턴 테스트를
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// ══════════════════════════════════════════════════════════
|
||
|
|
// 씬 뷰 기즈모 — 사거리 시각화
|
||
|
|
// ══════════════════════════════════════════════════════════
|
||
|
|
|
||
|
|
private void OnDrawGizmosSelected() // 함수를 실행할거에요 -> 씬 뷰 선택 시 사거리 시각화를
|
||
|
|
{
|
||
|
|
if (boss == null) return; // 중단할거에요 -> 보스 참조 없으면
|
||
|
|
|
||
|
|
// ─────────────── 근접 사거리 (초록) ─────────────────
|
||
|
|
Gizmos.color = Color.green; // 설정할거에요 -> Gizmo 색상을 초록으로
|
||
|
|
Gizmos.DrawWireSphere(boss.transform.position, boss.GetMeleeRange()); // 그릴거에요 -> 근접 사거리 구를
|
||
|
|
|
||
|
|
// ─────────────── 던지기 사거리 (청록) ─────────────────
|
||
|
|
Gizmos.color = Color.cyan; // 설정할거에요 -> Gizmo 색상을 청록으로
|
||
|
|
Gizmos.DrawWireSphere(boss.transform.position, boss.GetThrowRange()); // 그릴거에요 -> 던지기 사거리 구를
|
||
|
|
|
||
|
|
// ─────────────── 대시 발동 거리 (자주) ─────────────────
|
||
|
|
Gizmos.color = Color.magenta; // 설정할거에요 -> Gizmo 색상을 자주색으로
|
||
|
|
Gizmos.DrawWireSphere(boss.transform.position, boss.GetDashChaseRange()); // 그릴거에요 -> 대시 사거리 구를
|
||
|
|
|
||
|
|
// ─────────────── 내려찍기 판정 범위 (빨강) ─────────────────
|
||
|
|
Gizmos.color = new Color(1f, 0.2f, 0.2f, 0.5f); // 설정할거에요 -> Gizmo 색상을 반투명 빨강으로
|
||
|
|
Vector3 smashCenter = boss.transform.position + boss.transform.forward * boss.GetSmashForwardOffset(); // 계산할거에요 -> 내려찍기 중심을
|
||
|
|
Gizmos.DrawWireSphere(smashCenter, boss.GetSmashRadius()); // 그릴거에요 -> 내려찍기 판정 구를
|
||
|
|
|
||
|
|
// ─────────────── 휩쓸기 판정 범위 (주황) ─────────────────
|
||
|
|
Gizmos.color = new Color(1f, 0.6f, 0f, 0.5f); // 설정할거에요 -> Gizmo 색상을 반투명 주황으로
|
||
|
|
Gizmos.DrawWireSphere(boss.transform.position, boss.GetSweepRadius()); // 그릴거에요 -> 휩쓸기 판정 구를
|
||
|
|
|
||
|
|
// ─────────────── 대시+스매시 도착 범위 (노랑) ─────────────────
|
||
|
|
Gizmos.color = new Color(1f, 1f, 0f, 0.4f); // 설정할거에요 -> Gizmo 색상을 반투명 노랑으로
|
||
|
|
Gizmos.DrawWireSphere(boss.transform.position, boss.GetDashSmashArriveRange()); // 그릴거에요 -> 콤보 도착 거리 구를
|
||
|
|
|
||
|
|
// ─────────────── Phase/State 텍스트 (씬 뷰) ─────────────────
|
||
|
|
#if UNITY_EDITOR
|
||
|
|
string phaseText = boss.IsPhase3 ? "Phase 3 (광폭화)" // 결정할거에요 -> Phase 텍스트를
|
||
|
|
: boss.IsPhase2 ? "Phase 2"
|
||
|
|
: "Phase 1";
|
||
|
|
string stateText = $"{phaseText} | {boss.GetCurrentState()}"; // 조합할거에요 -> Phase + State 텍스트를
|
||
|
|
|
||
|
|
// 조건이 맞으면 실행할거에요 -> 콤보 진행 중이면
|
||
|
|
if (boss.GetComboCounter() > 0) // 조건을 확인할거에요 -> 콤보 카운터가
|
||
|
|
stateText += $" | 콤보 #{boss.GetComboCounter()}"; // 덧붙일거에요 -> 콤보 정보를
|
||
|
|
|
||
|
|
GUIStyle gizmoStyle = new GUIStyle(); // 생성할거에요 -> Gizmo 텍스트 스타일을
|
||
|
|
gizmoStyle.fontSize = 14; // 설정할거에요 -> 글자 크기를
|
||
|
|
gizmoStyle.fontStyle = FontStyle.Bold; // 설정할거에요 -> 글씨 무게를 굵게로
|
||
|
|
gizmoStyle.normal.textColor = boss.IsPhase3 ? Color.red // 설정할거에요 -> Phase별 색상을
|
||
|
|
: boss.IsPhase2 ? Color.yellow
|
||
|
|
: Color.white;
|
||
|
|
|
||
|
|
Vector3 labelPos = boss.transform.position + Vector3.up * 3.5f; // 계산할거에요 -> 보스 머리 위 위치를
|
||
|
|
UnityEditor.Handles.Label(labelPos, stateText, gizmoStyle); // 그릴거에요 -> 씬 뷰에 텍스트를
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
|
||
|
|
// ══════════════════════════════════════════════════════════
|
||
|
|
// 게임 화면 디버그 로그 (OnGUI)
|
||
|
|
// 플레이 중 좌측 상단에 보스 상태를 실시간 표시해요.
|
||
|
|
// ══════════════════════════════════════════════════════════
|
||
|
|
|
||
|
|
private void OnGUI() // 함수를 정의할거에요 -> 매 프레임 게임 화면에 UI를 그리는
|
||
|
|
{
|
||
|
|
if (!debugLogOnScreen) return; // 중단할거에요 -> 토글 꺼져있으면
|
||
|
|
if (boss == null) return; // 중단할거에요 -> 보스 참조 없으면
|
||
|
|
if (!boss.IsBattleStarted) return; // 중단할거에요 -> 전투 시작 전이면
|
||
|
|
|
||
|
|
// ─────────────── Phase 표시 (리치 텍스트) ─────────────────
|
||
|
|
string phase = boss.IsPhase3 ? "<color=red><b>Phase 3 (광폭화)</b></color>" // 결정할거에요 -> Phase 텍스트를 (색상 포함)
|
||
|
|
: boss.IsPhase2 ? "<color=yellow><b>Phase 2</b></color>"
|
||
|
|
: "<color=white><b>Phase 1</b></color>";
|
||
|
|
|
||
|
|
// ─────────────── HP 퍼센트 + 색상 ─────────────────
|
||
|
|
float maxHp = boss.GetMaxHP(); // 가져올거에요 -> 보스 최대 HP를
|
||
|
|
float currentHp = boss.GetCurrentHP(); // 가져올거에요 -> 보스 현재 HP를
|
||
|
|
float hpPercent = maxHp > 0 ? (currentHp / maxHp) * 100f : 0f; // 계산할거에요 -> HP 퍼센트를
|
||
|
|
string hpColor = hpPercent > 50f ? "green" : hpPercent > 25f ? "yellow" : "red"; // 결정할거에요 -> HP 구간별 색상을
|
||
|
|
|
||
|
|
// ─────────────── 콤보 표시 ─────────────────
|
||
|
|
int comboCounter = boss.GetComboCounter(); // 가져올거에요 -> 현재 콤보 카운터를
|
||
|
|
int maxCombo = boss.GetMaxComboCount(); // 가져올거에요 -> 최대 콤보 횟수를
|
||
|
|
string comboText = comboCounter > 0 // 결정할거에요 -> 콤보 텍스트를 (진행 중일 때만 표시)
|
||
|
|
? $" <color=cyan>콤보 #{comboCounter}/{maxCombo}</color>"
|
||
|
|
: "";
|
||
|
|
|
||
|
|
// ─────────────── 플레이어 거리 ─────────────────
|
||
|
|
float dist = boss.GetDistanceToTarget(); // 가져올거에요 -> 플레이어까지 거리를
|
||
|
|
|
||
|
|
// ─────────────── 플레이어 행동 감지 상태 텍스트 ─────────────────
|
||
|
|
string behaviorText = boss.GetPlayerBehaviorText(); // 가져올거에요 -> 플레이어 행동 감지 텍스트를
|
||
|
|
|
||
|
|
// ─────────────── 직전 패턴 표시 ─────────────────
|
||
|
|
string lastPatternText = boss.GetLastPatternText(); // 가져올거에요 -> 직전 패턴 정보를
|
||
|
|
|
||
|
|
// ─────────────── 텍스트 조합 ─────────────────
|
||
|
|
string debugText = $"{phase}{comboText}\n" // 조합할거에요 -> 전체 디버그 텍스트를
|
||
|
|
+ $"HP: <color={hpColor}>{currentHp:F0}/{maxHp:F0} ({hpPercent:F0}%)</color>\n"
|
||
|
|
+ $"State: <color=white>{boss.GetCurrentState()}</color> | Last: <color=white>{lastPatternText}</color>\n"
|
||
|
|
+ $"거리: <color=white>{dist:F1}m</color> | 쿨타임: <color=white>{boss.GetAttackTimer():F1}s</color>\n"
|
||
|
|
+ $"간격: <color=white>{boss.GetPatternInterval():F2}s</color> {behaviorText}";
|
||
|
|
|
||
|
|
// ─────────────── 리치 텍스트 지원 스타일 ─────────────────
|
||
|
|
GUIStyle richStyle = new GUIStyle(GUI.skin.box); // 생성할거에요 -> 리치 텍스트 스타일을
|
||
|
|
richStyle.richText = true; // 활성화할거에요 -> <color>, <b> 등 리치 텍스트 파싱을
|
||
|
|
richStyle.fontSize = 14; // 설정할거에요 -> 글자 크기를
|
||
|
|
richStyle.alignment = TextAnchor.UpperLeft; // 설정할거에요 -> 좌측 상단 정렬로
|
||
|
|
richStyle.normal.textColor = Color.white; // 설정할거에요 -> 기본 글자 색을 하양으로
|
||
|
|
richStyle.padding = new RectOffset(10, 10, 8, 8); // 설정할거에요 -> 안쪽 여백을
|
||
|
|
|
||
|
|
// ─────────────── 화면 좌측 상단에 그리기 ─────────────────
|
||
|
|
GUI.Box(new Rect(10, 10, 360, 120), debugText, richStyle); // 그릴거에요 -> 좌측 상단에 보스 상태 박스를
|
||
|
|
}
|
||
|
|
}
|