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 = FindObjectOfType();
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
}
}