ui
This commit is contained in:
@@ -1,49 +1,69 @@
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
// 화면 하단 등에 고정된 스크린 스페이스 대사 HUD 싱글턴.
|
||||
// DialogPlayer가 대사 노드를 재생할 때 Show()로 화자 이름 + 대사를 표시한다.
|
||||
// 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; }
|
||||
|
||||
[Header("Refs")]
|
||||
[SerializeField] private GameObject _panel; // 대사 패널(토글 대상). 보통 이 오브젝트의 자식.
|
||||
[SerializeField] private TMP_Text _speakerName;
|
||||
[SerializeField] private TMP_Text _dialogueText;
|
||||
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;
|
||||
Hide();
|
||||
_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 (_speakerName != null)
|
||||
{
|
||||
string speakerName = !string.IsNullOrEmpty(speakerNameOverride) ? speakerNameOverride
|
||||
: speaker != null ? speaker.Name : string.Empty;
|
||||
_speakerName.text = DialogVariables.Format(speakerName); // {key} 토큰 치환
|
||||
}
|
||||
if (_dialogueText != null)
|
||||
_dialogueText.text = DialogVariables.Format(text); // {key} 토큰 치환
|
||||
if (!EnsureRefs()) return;
|
||||
|
||||
if (_panel != null) _panel.SetActive(true);
|
||||
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 (_dialogueText != null) _dialogueText.text = string.Empty;
|
||||
if (!EnsureRefs()) return;
|
||||
if (_speakerName != null) _speakerName.text = string.Empty;
|
||||
if (_panel != null) _panel.SetActive(false);
|
||||
if (_dialogText != null) _dialogText.text = string.Empty;
|
||||
if (_panel != null) _panel.style.display = DisplayStyle.None;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user