using System; using UnityEngine; using Colosseum.UI; using Colosseum.Player; namespace Colosseum.Enemy { /// /// 보스 영역 트리거. /// 플레이어가 이 영역에 진입하면 연결된 보스의 체력바 UI를 표시합니다. /// [RequireComponent(typeof(Collider))] public class BossArea : MonoBehaviour { [Header("Boss Reference")] [Tooltip("이 영역에 연결된 보스")] [SerializeField] private BossEnemy boss; [Header("UI Settings")] [Tooltip("보스 체력바 UI (없으면 씬에서 자동 검색)")] [SerializeField] private BossHealthBarUI bossHealthBarUI; [Header("Trigger Settings")] [Tooltip("플레이어 퇴장 시 UI 숨김 여부")] [SerializeField] private bool hideOnExit = false; [Tooltip("영역 진입 시 한 번만 표시")] [SerializeField] private bool showOnceOnly = false; // 이벤트 /// /// 플레이어 진입 시 호출 /// public event Action OnPlayerEnter; /// /// 플레이어 퇴장 시 호출 /// public event Action OnPlayerExit; // 상태 private bool hasShownUI = false; private bool isPlayerInArea = false; private Collider triggerCollider; [Header("Debug")] [SerializeField] private bool debugMode = false; /// /// 연결된 보스 /// public BossEnemy Boss => boss; /// /// 플레이어가 영역 내에 있는지 여부 /// public bool IsPlayerInArea => isPlayerInArea; private void Awake() { // Collider 설정 확인 triggerCollider = GetComponent(); if (triggerCollider != null && !triggerCollider.isTrigger) { Debug.LogWarning($"[BossArea] {name}: Collider가 Trigger가 아닙니다. 자동으로 Trigger로 설정합니다."); triggerCollider.isTrigger = true; } } private void Start() { // BossHealthBarUI 자동 검색 if (bossHealthBarUI == null) { bossHealthBarUI = FindFirstObjectByType(); if (bossHealthBarUI == null) { Debug.LogWarning($"[BossArea] {name}: BossHealthBarUI를 찾을 수 없습니다."); } } // 보스 참조 확인 if (boss == null) { Debug.LogWarning($"[BossArea] {name}: 연결된 보스가 없습니다."); } } private void OnTriggerEnter(Collider other) { // 이미 표시했고 한 번만 표시 설정이면 무시 if (showOnceOnly && hasShownUI) return; // 플레이어 확인 (태그 또는 컴포넌트) if (!IsPlayer(other, out var playerController)) return; isPlayerInArea = true; ShowBossHealthBar(); OnPlayerEnter?.Invoke(); if (debugMode) Debug.Log($"[BossArea] {name}: 플레이어 진입 - 보스: {boss?.name ?? "없음"}"); } private void OnTriggerExit(Collider other) { // 플레이어 확인 if (!IsPlayer(other, out var playerController)) return; isPlayerInArea = false; if (hideOnExit) { HideBossHealthBar(); } OnPlayerExit?.Invoke(); if (debugMode) Debug.Log($"[BossArea] {name}: 플레이어 퇴장"); } /// /// 보스 체력바 표시 /// public void ShowBossHealthBar() { if (boss == null || bossHealthBarUI == null) return; // BossHealthBarUI에 보스 설정 bossHealthBarUI.SetBoss(boss); hasShownUI = true; } /// /// 보스 체력바 숨김 /// public void HideBossHealthBar() { if (bossHealthBarUI == null) return; bossHealthBarUI.gameObject.SetActive(false); } /// /// 플레이어 여부 확인 /// private bool IsPlayer(Collider other, out PlayerNetworkController playerController) { playerController = null; // 1. 태그로 확인 if (other.CompareTag("Player")) { playerController = other.GetComponent(); return true; } // 2. 컴포넌트로 확인 playerController = other.GetComponent(); if (playerController != null) return true; // 3. 부모에서 검색 playerController = other.GetComponentInParent(); return playerController != null; } /// /// 보스 수동 설정 /// public void SetBoss(BossEnemy newBoss) { boss = newBoss; } /// /// UI 수동 설정 /// public void SetHealthBarUI(BossHealthBarUI ui) { bossHealthBarUI = ui; } /// /// 상태 초기화 (재진입 허용) /// public void ResetState() { hasShownUI = false; isPlayerInArea = false; } #region Debug Gizmos private void OnDrawGizmos() { if (!debugMode) return; // 영역 시각화 Gizmos.color = new Color(1f, 0.5f, 0f, 0.3f); // 주황색 반투명 var col = GetComponent(); if (col is BoxCollider boxCol) { Gizmos.matrix = transform.localToWorldMatrix; Gizmos.DrawCube(boxCol.center, boxCol.size); } else if (col is SphereCollider sphereCol) { Gizmos.DrawSphere(transform.position + sphereCol.center, sphereCol.radius); } else if (col is CapsuleCollider capsuleCol) { // 캡슐은 구+실린더로 근접 표현 Gizmos.DrawWireSphere(transform.position + capsuleCol.center, capsuleCol.radius); } // 보스 연결 표시 if (boss != null) { Gizmos.color = Color.red; Gizmos.DrawLine(transform.position, boss.transform.position); } } private void OnDrawGizmosSelected() { // 선택 시 더 명확하게 표시 Gizmos.color = new Color(1f, 0.3f, 0f, 0.5f); var col = GetComponent(); if (col is BoxCollider boxCol) { Gizmos.matrix = transform.localToWorldMatrix; Gizmos.DrawCube(boxCol.center, boxCol.size); } } #endregion } }