using System; using System.Threading; using System.Threading.Tasks; using Febucci.UI.Core; using UnityEngine; using AibisDream.Utility; using AibisDream.Framework; namespace AibisDream { public class CenterText : MonoBehaviour, ILineView { [SerializeField] private TypewriterCore content; [SerializeField] private GameObject box; private CancellationTokenSource _autoHideToken; private event Action OnTextShowed; // ---------------------------- 显示逻辑 ---------------------------- public void RunLine(LineSyncToken syncToken) { // 先中断结束事件 _autoHideToken?.Cancel(); _autoHideToken = null; OnTextShowed = null; // 先停止旧动画并准备好激活状态,避免 OnEnable 或旧动画完成事件命中新 token。 content.StopShowingText(); box.SetActive(true); content.StopShowingText(); content.TextAnimator.SetText(string.Empty); // 注册事件 OnTextShowed += syncToken.TextShown; syncToken.SkipTextAnima += () => content.SkipTypewriter(); syncToken.OnAdvance += AfterAdvance; // 播放文字 ApplyTextSpeedSnapshot(); syncToken.TextStart(); content.ShowText(syncToken.lineInfo.lineText); } private void ApplyTextSpeedSnapshot() { content.resetTypingSpeedAtStartup = false; content.SetTypewriterSpeed(TextSpeedSettings.CurrentMultiplier); } private async void AfterAdvance() { _autoHideToken = new CancellationTokenSource(); try { await Task.Delay(ConstRef.AutoHideDelay, _autoHideToken.Token); HideDialog(); } catch (TaskCanceledException) { // 忽略取消 } } public void HideDialog() { box.SetActive(false); } // ---------------------------- 生命周期 ---------------------------- private void Awake() { box.SetActive(false); } private void Start() { DialogUIManager.Instance.RegisterScreenView(DialogViewType.CenterText, this); RegisterEvents(); } private void OnDestroy() { DialogUIManager.Instance.UnRegisterScreenView(DialogViewType.CenterText); UnregisterEvents(); OnTextShowed = null; } private void RegisterEvents() { // 全局事件 EnumEventSystem.Global.Register(DialogEventEnum.OptionShow, OnOptionShow); // 文本事件 content.onTextShowed.AddListener(TextShowed); } private void UnregisterEvents() { // 全局事件 EnumEventSystem.Global.UnRegister(DialogEventEnum.OptionShow, OnOptionShow); // 文本事件 content.onTextShowed.RemoveListener(TextShowed); } private void TextShowed() { OnTextShowed?.Invoke(); OnTextShowed = null; } private void OnOptionShow() { _autoHideToken?.Cancel(); _autoHideToken = null; HideDialog(); } } }