87 lines
4.3 KiB
C#
87 lines
4.3 KiB
C#
// ─────────────────────────────────────────────────────────────────────────────
|
|
// WLTextFxUtil.cs — 전투 텍스트 연출 3종이 공유하는 소소한 UI 조립 헬퍼 (WL-813g · #813)
|
|
//
|
|
// KillChainText · LootToast · StatPopup 이 자기 노드를 스스로 만든다(BuildIfNeeded 패턴 · 813c BossHpBar 선례).
|
|
// 프리팹에는 **빈 노드 1개 + 컴포넌트**만 들어가고 자식·좌표는 런타임에 만든다 →
|
|
// NewGameUI.prefab diff 를 "노드 추가"로만 유지한다(발주서 §2 ⓒ).
|
|
//
|
|
// 값은 하나도 들고 있지 않다(전부 WLCombatTextSettings). 여기 있는 숫자는 Unity 기본값(앵커 0/1)뿐이다.
|
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
|
|
using TMPro;
|
|
using UnityEngine;
|
|
|
|
namespace WL.UI
|
|
{
|
|
internal static class WLTextFxUtil
|
|
{
|
|
internal const int UILayer = 5; // 813c 와 같은 UI 레이어 인덱스
|
|
|
|
/// <summary>이름으로 자식을 찾고 없으면 RectTransform 자식을 만든다.</summary>
|
|
internal static RectTransform NewChild(RectTransform parent, string name)
|
|
{
|
|
var t = parent.Find(name) as RectTransform;
|
|
if (t != null) return t;
|
|
var go = new GameObject(name, typeof(RectTransform));
|
|
go.layer = UILayer;
|
|
t = (RectTransform)go.transform;
|
|
t.SetParent(parent, false);
|
|
t.localScale = Vector3.one;
|
|
t.localRotation = Quaternion.identity;
|
|
return t;
|
|
}
|
|
|
|
/// <summary>부모를 가득 채우도록 늘린다.</summary>
|
|
internal static void Stretch(RectTransform rt)
|
|
{
|
|
rt.anchorMin = Vector2.zero; rt.anchorMax = Vector2.one;
|
|
rt.offsetMin = Vector2.zero; rt.offsetMax = Vector2.zero;
|
|
rt.pivot = new Vector2(0.5f, 0.5f);
|
|
}
|
|
|
|
/// <summary>자식 TextMeshProUGUI 를 만들거나 찾는다(레이캐스트 off · 폰트는 있으면 주입).</summary>
|
|
internal static TextMeshProUGUI NewText(RectTransform parent, string name, TMP_FontAsset font, TextAlignmentOptions align)
|
|
{
|
|
var t = NewChild(parent, name);
|
|
var label = t.GetComponent<TextMeshProUGUI>();
|
|
if (label == null) label = t.gameObject.AddComponent<TextMeshProUGUI>();
|
|
label.raycastTarget = false;
|
|
label.alignment = align;
|
|
// 줄바꿈·오버플로 API 는 TMP 버전마다 이름이 갈려(enableWordWrapping ↔ textWrappingMode) 건드리지 않는다 — 기본값 유지.
|
|
if (font != null) label.font = font;
|
|
return label;
|
|
}
|
|
|
|
/// <summary>px → 캔버스 유닛 계수(802b 규약 · 캔버스 폭 / 기준 폭). 캔버스가 없으면 1.</summary>
|
|
internal static float UnitsPerPx(Component c, WLCombatTextSettings s)
|
|
{
|
|
if (s == null) return 1f;
|
|
var canvas = c != null ? c.GetComponentInParent<Canvas>() : null;
|
|
return s.UnitsPerPx(canvas != null ? canvas.rootCanvas : null);
|
|
}
|
|
|
|
/// <summary>0 → 1 로 지난 비율(life 는 남은 시간).</summary>
|
|
internal static float Passed(float life, float lifeMax)
|
|
{
|
|
return lifeMax > 0f ? 1f - Mathf.Clamp01(life / lifeMax) : 1f;
|
|
}
|
|
|
|
/// <summary>fadeStart 비율 이후에만 1 → 0 으로 떨어지는 알파.</summary>
|
|
internal static float FadeAlpha(float passed, float fadeStart)
|
|
{
|
|
fadeStart = Mathf.Clamp01(fadeStart);
|
|
if (passed < fadeStart) return 1f;
|
|
if (fadeStart >= 1f) return 0f;
|
|
return 1f - Mathf.Clamp01((passed - fadeStart) / (1f - fadeStart));
|
|
}
|
|
|
|
/// <summary>등장 펀치 스케일(punchSeconds 안에 punchScale → 1 로 수렴).</summary>
|
|
internal static float PunchScale(float elapsed, float punchScale, float punchSeconds)
|
|
{
|
|
if (punchSeconds <= 0f || punchScale <= 1f) return 1f;
|
|
float k = Mathf.Clamp01(elapsed / punchSeconds);
|
|
return Mathf.Lerp(punchScale, 1f, k * k);
|
|
}
|
|
}
|
|
}
|