Files
aibis-dream/Assets/Scripts/UI/DialogUI/DialogUIManager.cs
T

168 lines
5.7 KiB
C#

using AibisDream.Framework;
using AibisDream.Kit;
using AibisDream.UI;
using TMPro;
using UnityEngine;
namespace AibisDream
{
public class DialogUIManager : Singleton<DialogUIManager>
{
[SerializeField] private LineRunner lineView;
[SerializeField] private OptionView optionView;
[SerializeField] private TMP_Text widthEstimation;
private CanvasGroup _canvasGroup;
private BubbleSlotGroupData? _pendingBubbleData;
public override void OnSingletonInit()
{
_canvasGroup = GetComponent<CanvasGroup>();
if (_canvasGroup == null)
{
_canvasGroup = gameObject.AddComponent<CanvasGroup>();
}
EnumEventSystem.Global.Register<DialogEventEnum, LineInfo>(DialogEventEnum.LineStart, AddDialogueLine);
EnumEventSystem.Global.Register<DialogEventEnum, LineInfo>(DialogEventEnum.LineHistoryAppend, AddDialogueLine);
EnumEventSystem.Global.Register<DialogEventEnum, LineInfo>(DialogEventEnum.OptionSelected, AddDialogueLine);
EnumEventSystem.Global.Register(DialogEventEnum.LineEnd, ApplyPendingBubbleLoad);
EnumEventSystem.Global.Register(EventEnum.NextYarn, CleanDialogHistory);
EnumEventSystem.Global.Register(GameLifecycleEvent.SessionEnded, CleanDialogHistory);
EnumEventSystem.Global.Register(GameLifecycleEvent.SessionEnded, ClearPendingBubbleLoad);
EnumEventSystem.Global.Register(GameLifecycleEvent.SessionPaused, CloseCanvas);
EnumEventSystem.Global.Register(GameLifecycleEvent.SessionResumed, OpenCanvas);
}
public override void OnSingletonDestroy()
{
ClearPendingBubbleLoad();
EnumEventSystem.Global.UnRegister<DialogEventEnum, LineInfo>(DialogEventEnum.LineStart, AddDialogueLine);
EnumEventSystem.Global.UnRegister<DialogEventEnum, LineInfo>(DialogEventEnum.LineHistoryAppend, AddDialogueLine);
EnumEventSystem.Global.UnRegister<DialogEventEnum, LineInfo>(DialogEventEnum.OptionSelected, AddDialogueLine);
EnumEventSystem.Global.UnRegister(DialogEventEnum.LineEnd, ApplyPendingBubbleLoad);
EnumEventSystem.Global.UnRegister(EventEnum.NextYarn, CleanDialogHistory);
EnumEventSystem.Global.UnRegister(GameLifecycleEvent.SessionEnded, CleanDialogHistory);
EnumEventSystem.Global.UnRegister(GameLifecycleEvent.SessionEnded, ClearPendingBubbleLoad);
EnumEventSystem.Global.UnRegister(GameLifecycleEvent.SessionPaused, CloseCanvas);
EnumEventSystem.Global.UnRegister(GameLifecycleEvent.SessionResumed, OpenCanvas);
}
private void AddDialogueLine(LineInfo line)
{
if (line.character.dialogViewType == DialogViewType.Task)
{
return;
}
var panel = UIManager.Instance.GetPanel<InGameTerminalPanel>();
panel?.AppendDialogLine(line);
}
private void CleanDialogHistory()
{
var panel = UIManager.Instance.GetPanel<InGameTerminalPanel>();
panel?.ClearDialog();
}
public void CloseCanvas()
{
gameObject.SetActive(false);
}
public void OpenCanvas()
{
gameObject.SetActive(true);
}
/// <summary>
/// 仅隐藏对话视觉,不影响打字机、推进与选项交互。
/// </summary>
public void SetDialogVisualVisible(bool visible)
{
if (_canvasGroup == null)
{
_canvasGroup = GetComponent<CanvasGroup>();
}
_canvasGroup.alpha = visible ? 1f : 0f;
}
public void HideDialog()
{
lineView.HideDialog();
optionView.HideDialog();
}
public void RegisterScreenView(DialogViewType dialogViewType, ILineView screenView)
{
lineView.RegisterView(dialogViewType, screenView);
}
public void UnRegisterScreenView(DialogViewType dialogViewType)
{
lineView.UnRegisterView(dialogViewType);
}
public void LoadBubbles(BubbleSlotGroupData data)
{
var token = DialogController.Instance != null
? DialogController.Instance.lineSyncToken
: null;
if (token != null && token.state != LineSyncState.Advanced)
{
// 同一行内的连续请求采用最后一次请求,当前气泡保留到台词推进。
_pendingBubbleData = data;
return;
}
_pendingBubbleData = null;
ApplyBubbleLoadImmediately(data);
}
private void ApplyPendingBubbleLoad()
{
if (!_pendingBubbleData.HasValue)
{
return;
}
var data = _pendingBubbleData.Value;
_pendingBubbleData = null;
ApplyBubbleLoadImmediately(data);
}
private void ApplyBubbleLoadImmediately(BubbleSlotGroupData data)
{
lineView.LoadBubbleData(data);
optionView.LoadBubbles(data);
}
private void ClearPendingBubbleLoad()
{
_pendingBubbleData = null;
}
public float EstimateTextWidth(string text, float fontSize)
{
widthEstimation.fontSize = fontSize;
widthEstimation.text = text;
widthEstimation.ForceMeshUpdate();
return widthEstimation.preferredWidth;
}
}
public enum DialogViewType
{
Default,
StandardBubble,
OnelineBox,
Screen,
CenterText,
CenterOption,
Task,
Log
}
}