using System.Collections;
using UnityEngine;
using UnityEngine.UI;
namespace Streamingle.Contents.BossRaid
{
///
/// 데미지 숫자 팝업을 생성하고 관리합니다.
/// WorldSpace Canvas에서 숫자가 튀어나와 중력으로 떨어집니다.
///
public class DamagePopup : MonoBehaviour
{
#region Fields
[Header("프리팹")]
[SerializeField]
[Tooltip("데미지 숫자 프리팹. 없으면 자동 생성")]
private GameObject popupPrefab;
[Header("일반 히트")]
[SerializeField] private Color normalColor = Color.white;
[SerializeField] private int normalFontSize = 32;
[Header("크리티컬")]
[SerializeField] private Color criticalColor = new Color(1f, 0.2f, 0.2f);
[SerializeField] private int criticalFontSize = 48;
[Header("애니메이션")]
[SerializeField] private float popupDuration = 1.2f;
[SerializeField] private float upwardForce = 3f;
[SerializeField] private float gravity = 8f;
[Header("위치")]
[SerializeField]
[Tooltip("바운더리 외곽 여유 (콜라이더 경계 밖으로 얼마나 더 퍼질지)")]
private float spreadMargin = 0.5f;
[SerializeField]
[Tooltip("바운더리가 없을 때 기본 X 퍼짐")]
private float fallbackSpreadX = 1f;
[SerializeField]
[Tooltip("바운더리가 없을 때 기본 높이 오프셋")]
private float fallbackHeightOffset = 1.5f;
private Canvas _worldCanvas;
private Font _font;
#endregion
#region Unity Messages
private void Awake()
{
_font = BossRaidFontLoader.Load();
EnsureWorldCanvas();
}
#endregion
#region Public Methods
///
/// 데미지 숫자를 생성합니다.
/// bounds가 있으면 바운더리 외곽 범위에서 랜덤 위치에 생성됩니다.
///
public void Spawn(int damage, bool isCritical, Vector3 worldPosition, Bounds? bounds = null)
{
EnsureWorldCanvas();
var go = CreatePopupObject();
var text = go.GetComponent();
if (text == null) text = go.GetComponentInChildren();
if (text != null)
{
text.text = damage.ToString();
text.color = isCritical ? criticalColor : normalColor;
text.fontSize = isCritical ? criticalFontSize : normalFontSize;
if (isCritical) text.fontStyle = FontStyle.Bold;
}
Vector3 spawnPos;
if (bounds.HasValue)
{
var b = bounds.Value;
// 바운더리 외곽에서 랜덤 위치
float halfX = b.extents.x + spreadMargin;
float topY = b.max.y + spreadMargin;
float bottomY = b.center.y;
spawnPos = new Vector3(
b.center.x + Random.Range(-halfX, halfX),
Random.Range(bottomY, topY),
b.center.z
);
}
else
{
spawnPos = worldPosition + new Vector3(
Random.Range(-fallbackSpreadX, fallbackSpreadX),
fallbackHeightOffset + Random.Range(0f, 1f),
0f
);
}
go.transform.position = spawnPos;
StartCoroutine(AnimatePopup(go, isCritical));
}
#endregion
#region Private Methods
private void EnsureWorldCanvas()
{
if (_worldCanvas != null) return;
var canvasObj = new GameObject("BossRaid_DamagePopupCanvas");
canvasObj.transform.SetParent(transform);
_worldCanvas = canvasObj.AddComponent