Files
StoryGame_Unity/Assets/02_Scripts/_UI/Communication/DialogHud.cs
2026-07-26 18:47:19 +09:00

70 lines
2.6 KiB
C#

using UnityEngine;
using UnityEngine.UIElements;
// UI Toolkit 버전 대사 HUD. DialogUI.uxml의 요소(#SpeakerName / #DialogText / #DialogField)를 잡아
// 화자 이름 + 대사를 표시한다.
// 공개 API(Instance / Show / Hide)는 기존 uGUI 버전과 동일 — DialogPlayer는 수정 없이 그대로 쓴다.
[RequireComponent(typeof(UIDocument))]
public class DialogHud : MonoBehaviour
{
public static DialogHud Instance { get; private set; }
private UIDocument _document;
private VisualElement _panel; // 대사 패널(#DialogField) — 토글 대상
private Label _speakerName;
private Label _dialogText;
private bool _ready;
private void Awake()
{
if (Instance != null && Instance != this) { Destroy(gameObject); return; }
Instance = this;
_document = GetComponent<UIDocument>();
}
// 시작 시 숨김 (이 시점엔 UIDocument의 visual tree가 준비돼 있다)
private void Start() => Hide();
private void OnDestroy()
{
if (Instance == this) Instance = null;
}
// rootVisualElement가 준비된 뒤 한 번만 요소를 캐싱한다.
// (스크립트 실행 순서상 UIDocument보다 먼저 OnEnable이 돌 수 있어 지연 초기화로 안전하게 처리)
private bool EnsureRefs()
{
if (_ready) return true;
var root = _document != null ? _document.rootVisualElement : null;
if (root == null) return false;
_panel = root.Q<VisualElement>("DialogField");
_speakerName = root.Q<Label>("SpeakerName");
_dialogText = root.Q<Label>("DialogText");
_ready = true;
return true;
}
// 화자 이름 + 대사 표시.
// - speakerNameOverride가 비어있지 않으면 CharacterData.Name 대신 그 이름을 표시한다 (예: "???")
public void Show(CharacterData speaker, string text, string speakerNameOverride = null)
{
if (!EnsureRefs()) return;
string speakerName = !string.IsNullOrEmpty(speakerNameOverride) ? speakerNameOverride
: speaker != null ? speaker.Name : string.Empty;
if (_speakerName != null) _speakerName.text = DialogVariables.Format(speakerName); // {key} 토큰 치환
if (_dialogText != null) _dialogText.text = DialogVariables.Format(text);
if (_panel != null) _panel.style.display = DisplayStyle.Flex;
}
public void Hide()
{
if (!EnsureRefs()) return;
if (_speakerName != null) _speakerName.text = string.Empty;
if (_dialogText != null) _dialogText.text = string.Empty;
if (_panel != null) _panel.style.display = DisplayStyle.None;
}
}