using System; using System.Collections; using System.Collections.Generic; using System.Linq; using AibisDream.Framework; using AibisDream.Kit; using AibisDream.Utility; 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 Action _nextStep; private GameObject _textItemPrefab; private Queue _lineQueue; 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); // TODO 调整估算文本框的宽度 } 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 IEnumerator ShowText(string targetText) { EnumEventSystem.Global.Send(DialogEventEnum.LineShown); yield return new WaitForSeconds(0.5f); EnumEventSystem.Global.Send(DialogEventEnum.LineEnd); _nextStep.Invoke(); } public void ClearTextScreen() { while (_lineQueue.Count > 0) { var text = _lineQueue.Dequeue(); Destroy(text.gameObject); } } #endregion #region 对话框功能实现 public void ShowLine(string dialogLine, CharacterVo character, Action nextStep, string lineId, bool isAutoSkip = false) { 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); // 播放完成后,顿0.3秒执行下一步 textItemTypewriter.onTextShowed.AddListener(AutoNextStep); // 每行自动跳过 _nextStep = nextStep; // 强制更新布局 LayoutRebuilder.ForceRebuildLayoutImmediate(textRoot); } private void AutoNextStep() { } 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.linkCount; } private int CalcTotalLineNum() { return _lineQueue.Select(x => x.GetComponent().textInfo.linkCount).Sum(); } } }