using System; using System.Collections.Generic; using System.Linq; using AibisDream.Framework; using AibisDream.Kit; using AibisDream.Utility; using DG.Tweening; using Febucci.UI; using TMPro; using UnityEngine; using UnityEngine.UI; namespace AibisDream.FixSystem { public class ScreenSystem : MonoBehaviour, IDialogView { #region 索引 [SerializeField] private TMP_Text title; [SerializeField] private RectTransform textRoot; [SerializeField] private TMP_Text textForEstimation; private GameObject _textItemPrefab; private Queue _lineQueue; public BubbleSlotGroup BubbleSlotGroup { get; private set; } public TaskScreen TaskScreen { get; private set; } public int maxLineNum = 10; #endregion private void Awake() { InitComponentRefs(); Register(); } private void InitComponentRefs() { TaskScreen = GetComponentInChildren(); _lineQueue = new Queue(); _textItemPrefab = ResourceKit.LoadAssetSync(ConstRef.ScreenTextName); BubbleSlotGroup = GetComponentInChildren(); } private void Register() { FixSystemCenter.SystemDic.Register(this); DialogCanvasManager.Instance.RegisterDialogView(DialogViewType.Screen, this); DialogCanvasManager.Instance.RegisterDialogView(DialogViewType.Task, TaskScreen); } private void OnDestroy() { FixSystemCenter.SystemDic.Unregister(); DialogCanvasManager.Instance.UnregisterDialogView(DialogViewType.Screen); DialogCanvasManager.Instance.UnregisterDialogView(DialogViewType.Task); } #region 基础功能 private void ShowTitle(string targetTitle) { title.text = targetTitle; } public void ClearTextScreen() { while (_lineQueue.Count > 0) { var text = _lineQueue.Dequeue(); Destroy(text.gameObject); } ShowTitle(string.Empty); } public void ShowTaskPanel() { TaskScreen.transform.DOLocalMoveX(-7.12f, 1f); } #endregion #region 对话框功能实现 public void ShowLine(string dialogLine, CharacterVo character, Action nextStep, string lineId, bool isAutoSkip = false) { Debug.Log($"[ScreenSystem] ShowLine - 原始文本: '{dialogLine}'"); if (string.IsNullOrWhiteSpace(dialogLine)) { dialogLine = " "; // Debug.Log("[ScreenSystem] ShowLine - 空文本被替换为空格"); } ShowTitle(character.GetActorName()); // 生成新文本组件 var textItem = Instantiate(_textItemPrefab, textRoot); var textItemTypewriter = textItem.GetComponent(); // 估算文本高度 var newLineNum = EstimateLineNum(dialogLine); var oldLineNum = CalcTotalLineNum(); if (newLineNum + oldLineNum > maxLineNum) { Destroy(_lineQueue.Dequeue().gameObject); } _lineQueue.Enqueue(textItemTypewriter); // 播放文本 textItemTypewriter.ShowText(dialogLine); textItemTypewriter.onTextShowed.AddListener(() => AfterLineShown(textItemTypewriter, nextStep)); // 强制更新布局 LayoutRebuilder.ForceRebuildLayoutImmediate(textRoot); Debug.Log($"[ScreenSystem] ShowLine - 文本播放开始,nextStep是否为null: {nextStep == null}"); } private void AfterLineShown(TypewriterByCharacter typewriter, Action nextStop) { Debug.Log("[ScreenSystem] AfterLineShown - 文本显示完成"); Debug.Log($"[ScreenSystem] AfterLineShown - nextStop是否为null: {nextStop == null}"); EnumEventSystem.Global.Send(DialogEventEnum.LineShown); ActionKit.Delay(0.1f, () => { Debug.Log("[ScreenSystem] AfterLineShown - 延迟结束,调用回调"); EnumEventSystem.Global.Send(DialogEventEnum.LineEnd); nextStop.Invoke(); Debug.Log("[ScreenSystem] AfterLineShown - 回调调用完成"); }).StartGlobal(); typewriter.onTextShowed.RemoveAllListeners(); } public void ShowOptions(DialogOption[] dialogueOptions) { Debug.Log("不能在显示屏显示对话"); } public void HideDialog() { // HideDialog应该由其他函数控制 } public bool TrySkipLine(bool isAutoSkip) { // 这里不能跳过对话 return true; } public void NextStep() { // 这里不能手动跳到下一行 } public void OnLocalizationChanged(string value) { // 屏幕不需要本地化 } #endregion private int EstimateLineNum(string text) { textForEstimation.text = text; textForEstimation.ForceMeshUpdate(); return textForEstimation.textInfo.lineCount; } private int CalcTotalLineNum() { return _lineQueue.Select(x => x.GetComponent().textInfo.lineCount).Sum(); } } }