198 lines
5.7 KiB
C#
198 lines
5.7 KiB
C#
using System;
|
|
using System.Collections;
|
|
using AibisDream.Framework;
|
|
using AibisDream.Kit;
|
|
using DG.Tweening;
|
|
using TMPro;
|
|
using UnityEngine;
|
|
|
|
namespace AibisDream.FixSystem
|
|
{
|
|
public class ScreenSystem : MonoBehaviour, IScreen, IDialogView
|
|
{
|
|
#region 效果参数
|
|
|
|
public float typeSpeed = 0.05f;
|
|
public int maxTextLine;
|
|
|
|
#endregion
|
|
|
|
#region 索引
|
|
|
|
[SerializeField] private TMP_Text title;
|
|
[SerializeField] private TMP_Text text;
|
|
private Action _nextStep;
|
|
|
|
private TextGenerator _generator;
|
|
private TextGenerationSettings _generationSettings;
|
|
|
|
private IUnRegister _plugOutRmv;
|
|
|
|
public TaskScreen TaskScreen { get; private set; }
|
|
|
|
#endregion
|
|
|
|
private void Awake()
|
|
{
|
|
InitComponentRefs();
|
|
Register();
|
|
}
|
|
|
|
private void InitComponentRefs()
|
|
{
|
|
_generator = new TextGenerator();
|
|
_generationSettings = new TextGenerationSettings
|
|
{
|
|
font = text.font.sourceFontFile,
|
|
fontSize = Mathf.RoundToInt(text.fontSize),
|
|
lineSpacing = text.lineSpacing,
|
|
horizontalOverflow = HorizontalWrapMode.Wrap,
|
|
verticalOverflow = VerticalWrapMode.Truncate,
|
|
generationExtents = new Vector2(text.rectTransform.rect.width, Mathf.Infinity),
|
|
resizeTextForBestFit = false
|
|
};
|
|
|
|
TaskScreen = GetComponentInChildren<TaskScreen>();
|
|
}
|
|
|
|
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 基础功能
|
|
|
|
public void ShowTitle(string targetTitle)
|
|
{
|
|
title.text = targetTitle;
|
|
}
|
|
|
|
public IEnumerator ShowText(string targetText)
|
|
{
|
|
// 先换行
|
|
if (!string.IsNullOrEmpty(text.text))
|
|
{
|
|
text.text += "\n";
|
|
}
|
|
// 先估算新增行数
|
|
var targetLineNum = EstimateLineNum(targetText);
|
|
// 截断超出屏幕的部分
|
|
var oldText = "";
|
|
if (targetLineNum + text.textInfo.lineCount > maxTextLine)
|
|
{
|
|
var cutLineNum = targetLineNum + text.textInfo.lineCount - maxTextLine;
|
|
if (cutLineNum <= text.textInfo.lineCount)
|
|
{
|
|
var lastCharIndex = text.textInfo.lineInfo[cutLineNum - 1].lastCharacterIndex;
|
|
if (lastCharIndex + 1 < text.text.Length)
|
|
{
|
|
oldText = text.text.Substring(lastCharIndex + 1);
|
|
}
|
|
else
|
|
{
|
|
oldText = string.Empty;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
oldText = text.text;
|
|
}
|
|
|
|
|
|
var targetLength = oldText.Length + targetText.Length;
|
|
|
|
// 逐个字符添加
|
|
yield return DOTween.To(() => oldText.Length, x => UpdateText(x, targetText, oldText), targetLength,
|
|
targetText.Length * typeSpeed).WaitForCompletion();
|
|
EnumEventSystem.Global.Send(DialogEventEnum.LineShown);
|
|
yield return new WaitForSeconds(0.5f);
|
|
EnumEventSystem.Global.Send(DialogEventEnum.LineEnd);
|
|
_nextStep.Invoke();
|
|
}
|
|
|
|
private int EstimateLineNum(string str)
|
|
{
|
|
var height = _generator.GetPreferredHeight(str, _generationSettings);
|
|
var lineHeight = text.fontSize * 1.2f; // 简单估算行高
|
|
|
|
return Mathf.CeilToInt(height / lineHeight);
|
|
}
|
|
|
|
private void UpdateText(int currentLength, string nextText, string oldText)
|
|
{
|
|
var appendLength = currentLength - oldText.Length;
|
|
text.text = oldText + nextText[..appendLength];
|
|
}
|
|
|
|
public void ClearTextScreen()
|
|
{
|
|
title.text = "";
|
|
text.SetText("");
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 对话框功能实现
|
|
|
|
public void ShowLine(string dialogLine, CharacterVo character, Action nextStep, string lineId, bool isAutoSkip = false)
|
|
{
|
|
ShowTitle(character.GetActorName());
|
|
StartCoroutine(ShowText(dialogLine));
|
|
// 每行自动跳过
|
|
_nextStep = nextStep;
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
/// <summary>
|
|
/// 屏幕接口
|
|
/// </summary>
|
|
public interface IScreen
|
|
{
|
|
// 显示标题文字
|
|
void ShowTitle(string title);
|
|
|
|
// 显示正文
|
|
IEnumerator ShowText(string text);
|
|
|
|
// 清空屏幕
|
|
void ClearTextScreen();
|
|
}
|
|
} |