Files
aibis-dream/Assets/Scripts/FixSystemNew/Screen System/ScreenSystem.cs
T
2025-06-14 21:50:00 +08:00

165 lines
4.9 KiB
C#

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<TypewriterByCharacter> _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<TaskScreen>();
_lineQueue = new Queue<TypewriterByCharacter>();
_textItemPrefab = ResourceKit.LoadAssetSync<GameObject>(ConstRef.ScreenTextName);
BubbleSlotGroup = GetComponentInChildren<BubbleSlotGroup>();
}
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<ScreenSystem>();
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.DOLocalMoveY(3.85f, 1f);
}
#endregion
#region 对话框功能实现
public void ShowLine(string dialogLine, CharacterVo character, Action nextStep, string lineId, bool isAutoSkip = false)
{
if (string.IsNullOrWhiteSpace(dialogLine))
{
dialogLine = " ";
}
ShowTitle(character.GetActorName());
// 生成新文本组件
var textItem = Instantiate(_textItemPrefab, textRoot);
var textItemTypewriter = textItem.GetComponent<TypewriterByCharacter>();
// 估算文本高度
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);
}
private void AfterLineShown(TypewriterByCharacter typewriter, Action nextStop)
{
EnumEventSystem.Global.Send(DialogEventEnum.LineShown);
ActionKit.Delay(0.3f, () =>
{
EnumEventSystem.Global.Send(DialogEventEnum.LineEnd);
nextStop.Invoke();
}).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.linkCount;
}
private int CalcTotalLineNum()
{
return _lineQueue.Select(x => x.GetComponent<TMP_Text>().textInfo.linkCount).Sum();
}
}
}