157 lines
4.7 KiB
C#
157 lines
4.7 KiB
C#
using System;
|
|
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 GameObject _textItemPrefab;
|
|
private Queue<TypewriterByCharacter> _lineQueue;
|
|
|
|
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);
|
|
// 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<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);
|
|
}
|
|
|
|
#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();
|
|
}
|
|
}
|
|
} |