Files
aibis-dream/Assets/Scripts/FixSystemNew/Screen System/ScreenSystem.cs
T
2026-02-03 20:49:52 +08:00

160 lines
5.1 KiB
C#

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<TypewriterByCharacter> _lineQueue;
public BubbleSlotGroup BubbleSlotGroup { get; private set; }
public TaskScreen TaskScreen { get; private set; }
[SerializeField] private FixLightSystem fixLightSystem;
public FixLightSystem FixLightSystem => fixLightSystem;
#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>();
// 如果没有手动指定,尝试自动获取 FixLightSystem
if (fixLightSystem == null)
{
fixLightSystem = GetComponentInChildren<FixLightSystem>();
}
}
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<ScreenSystem>();
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<TypewriterByCharacter>();
// 估算文本高度
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<TMP_Text>().textInfo.lineCount).Sum();
}
}
}