using System.Collections.Generic; using System.Globalization; using System.Linq; using AibisDream.Framework; using AibisDream.Utility; using DG.Tweening; using Febucci.UI; using Febucci.UI.Core; using TMPro; using UnityEngine; using UnityEngine.UI; namespace AibisDream.FixSystem { public class ScreenSystem : MonoBehaviour, ILineView { #region 索引 [SerializeField] private TMP_Text title; [SerializeField] private RectTransform textRoot; [SerializeField] private TMP_Text textForEstimation; [SerializeField] private int maxLineNum = 10; private GameObject _textItemPrefab; private Queue _lineQueue; public BubbleSlotGroup BubbleSlotGroup { get; private set; } public TaskScreen TaskScreen { get; private set; } #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); DialogUIManager.Instance.RegisterScreenView(DialogViewType.Screen, this); DialogUIManager.Instance.RegisterScreenView(DialogViewType.Task, TaskScreen); // StorageSystem.Instance.RegisterData(this); } private void OnDestroy() { FixSystemCenter.SystemDic.Unregister(); DialogUIManager.Instance.UnRegisterScreenView(DialogViewType.Screen); DialogUIManager.Instance.UnRegisterScreenView(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 public void RunLine(LineSyncToken token) { // 空格延长一点避免报错 if (string.IsNullOrWhiteSpace(token.lineInfo.lineText)) { token.lineInfo.lineText = " "; } // 显示标题 ShowTitle(token.lineInfo.character.GetActorName()); // 显示文本 TypewriterCore textItemTypewriter = AddText(token); token.TextStart(); // 强制更新布局 LayoutRebuilder.ForceRebuildLayoutImmediate(textRoot); } private float GetTextSpeedValue() { var textSpeedStr = SettingLoader.Instance.TryRead("TextSpeed", out string textSpeed) ? textSpeed : "1"; return float.TryParse(textSpeedStr, NumberStyles.Float, CultureInfo.InvariantCulture, out float result) ? result : 1f; } private void OnTextShown(LineSyncToken syncToken, TypewriterCore typewriter) { typewriter.onTextShowed.RemoveAllListeners(); syncToken.TextShown(); } private TypewriterByCharacter AddText(LineSyncToken token) { // 生成新文本组件 var textItem = Instantiate(_textItemPrefab, textRoot); var textItemTypewriter = textItem.GetComponent(); // 估算文本高度 var newLineNum = EstimateLineNum(token.lineInfo.lineText); var oldLineNum = CalcTotalLineNum(); if (newLineNum + oldLineNum > maxLineNum) { Destroy(_lineQueue.Dequeue().gameObject); } _lineQueue.Enqueue(textItemTypewriter); // 播放文本 textItemTypewriter.SetTypewriterSpeed(GetTextSpeedValue()); textItemTypewriter.onTextShowed.AddListener(() => OnTextShown(token, textItemTypewriter)); textItemTypewriter.ShowText(token.lineInfo.lineText); return textItemTypewriter; } 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(); } } }