대화구조 수정
This commit is contained in:
@@ -28,6 +28,10 @@ public class DialogHud : MonoBehaviour
|
||||
private string _speakerText = string.Empty;
|
||||
private Typewriter _typewriter;
|
||||
|
||||
// 강조 단어([[...]])의 맥동 연출. 지금 대사에 강조가 있을 때만 매 프레임 다시 그린다.
|
||||
private readonly TextGlow _glow = new();
|
||||
private bool _hasEmphasis;
|
||||
|
||||
// 같은 버전으로 콜백이 중복 호출될 때 헛일을 막는다 (Unity 권장 패턴)
|
||||
private int _uiVersion = -1;
|
||||
|
||||
@@ -66,9 +70,21 @@ private void OnUIReload(PanelRenderer panelRenderer, VisualElement root, int ver
|
||||
_speakerName = root.Q<Label>("SpeakerName");
|
||||
_dialogText = root.Q<Label>("DialogText");
|
||||
|
||||
// 글자별 정점 후처리 연결 — Label이 리로드로 새로 만들어질 때마다 다시 걸어야 한다
|
||||
if (_dialogText != null)
|
||||
_dialogText.PostProcessTextVertices = _glow.Process;
|
||||
|
||||
ApplyState(); // 첫 호출에선 _visible=false라 숨김 상태로 시작한다
|
||||
}
|
||||
|
||||
// 맥동은 매 프레임 정점을 다시 만들어야 보이므로 리페인트를 요청한다.
|
||||
// 강조가 없는 대사에서는 아무 일도 하지 않는다.
|
||||
private void Update()
|
||||
{
|
||||
if (_visible && _hasEmphasis && _glow.IsAnimating && _dialogText != null)
|
||||
_dialogText.MarkDirtyRepaint();
|
||||
}
|
||||
|
||||
// 화자 이름 + 대사 표시. 대사는 style(없으면 기본 스타일)로 한 글자씩 드러난다.
|
||||
// - speakerNameOverride가 비어있지 않으면 CharacterData.Name 대신 그 이름을 표시한다 (예: "???")
|
||||
// - style은 이 대사만의 연출 (DialogNode.Typewriter). 둘 다 비면 한 번에 표시된다.
|
||||
@@ -81,15 +97,22 @@ private void OnUIReload(PanelRenderer panelRenderer, VisualElement root, int ver
|
||||
_speakerText = DialogVariables.Format(speakerName); // {key} 토큰 치환
|
||||
_visible = true;
|
||||
|
||||
var effective = style != null ? style : _defaultStyle;
|
||||
|
||||
// 토큰 치환 → 강조 표기 펼치기 순서. 토큰 값 안에 [[...]]가 있어도 강조가 적용된다.
|
||||
string body = DialogMarkup.Expand(DialogVariables.Format(text), effective);
|
||||
_hasEmphasis = body.Contains("<link=" + TextGlow.LINK_ID);
|
||||
_glow.SetStyle(effective);
|
||||
|
||||
// Begin이 진행 콜백으로 ApplyState를 부르므로 _visible을 먼저 세워 둔다
|
||||
_typewriter.Begin(DialogVariables.Format(text), style != null ? style : _defaultStyle,
|
||||
destroyCancellationToken);
|
||||
_typewriter.Begin(body, effective, destroyCancellationToken);
|
||||
}
|
||||
|
||||
public void Hide()
|
||||
{
|
||||
_speakerText = string.Empty;
|
||||
_visible = false;
|
||||
_hasEmphasis = false;
|
||||
_typewriter.Clear(); // 타이핑 사운드 정지 + ApplyState 호출
|
||||
}
|
||||
|
||||
@@ -97,7 +120,17 @@ public void Hide()
|
||||
// 요소가 아직 없으면(리로드 콜백 전) 조용히 넘어가고, 콜백이 오면 같은 함수로 복원된다.
|
||||
private void ApplyState()
|
||||
{
|
||||
if (_speakerName != null) _speakerName.text = _speakerText;
|
||||
if (_speakerName != null)
|
||||
{
|
||||
_speakerName.text = _speakerText;
|
||||
|
||||
// 서술(화자 없는 대사)에서는 이름표를 감추되 **자리는 그대로 남긴다**.
|
||||
// display:None은 레이아웃에서 요소를 빼버려서 DialogText(flex-grow:1)가 그 공간까지
|
||||
// 차지해 대사가 위로 올라온다. visibility:Hidden은 position이 Relative인 요소의
|
||||
// 공간을 유지하므로, 화자가 있으나 없으나 대사 영역 크기가 동일하다.
|
||||
_speakerName.style.visibility = string.IsNullOrEmpty(_speakerText)
|
||||
? Visibility.Hidden : Visibility.Visible;
|
||||
}
|
||||
|
||||
if (_dialogText != null)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user