代码:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using TMPro;
using UnityEngine;
/// <summary>
/// 文本预处理
/// </summary>
public class AdvanceTextPreprocessor : ITextPreprocessor
{
public Dictionary<int, float> IntervalDic;
public AdvanceTextPreprocessor()
{
IntervalDic = new Dictionary<int, float>();
}
public string PreprocessText(string text)
{
IntervalDic.Clear();
string processingText = text;
string pattern = @"<(\d+)(\.\d+)?>";
Match match = Regex.Match(processingText, pattern);
while (match.Success)
{
string lable = match.Value.Substring(1, match.Length - 2);
//Debug.LogError(lable);
if(float.TryParse(lable, out float result))
{
IntervalDic[match.Index - 1] = result;
}
processingText = processingText.Remove(match.Index, match.Length);
match = Regex.Match(processingText, pattern);
}
return processingText;
}
}
public class AdvancedText : TextMeshProUGUI
{
private float m_defaultInterval = 0.06f;
private int m_typingIndex;
private Coroutine startCoro;
//textPreprocessor 接口类型
private AdvanceTextPreprocessor selfPreprocessor => (AdvanceTextPreprocessor) textPreprocessor;
public AdvancedText()
{
textPreprocessor = new AdvanceTextPreprocessor();
}
public void ShowTextByTyping(string content)
{
SetText(content);
startCoro = StartCoroutine(Typing());
}
public void ImmediatelyShow()
{
StopCoroutine(startCoro);
ForceMeshUpdate();
for (int i = 0; i < m_characterCount; i++)
{
SetSingleCharacterAlpha(i, 255);
}
}
IEnumerator Typing()
{
ForceMeshUpdate();
for (int i = 0; i < m_characterCount; i++)
{
SetSingleCharacterAlpha(i, 0);
}
m_typingIndex = 0;
while (m_typingIndex < m_characterCount)
{
if (textInfo.characterInfo[m_typingIndex].isVisible)
{
StartCoroutine(FadeInCharacter(m_typingIndex));
}
if (selfPreprocessor.IntervalDic.TryGetValue(m_typingIndex, out float result))
{
yield return new WaitForSecondsRealtime(result);
}
else
{
yield return new WaitForSecondsRealtime(m_defaultInterval);
}
m_typingIndex++;
}
}
private void SetSingleCharacterAlpha(int index, byte newAlpha)
{
TMP_CharacterInfo charInfo = textInfo.characterInfo[index];
//材质实例索引
int matIndex = charInfo.materialReferenceIndex;
//顶点索引
int vertIndex = charInfo.vertexIndex;
for (int i = 0; i < 4; i++)
{
textInfo.meshInfo[matIndex].colors32[vertIndex + i].a = newAlpha;
}
UpdateVertexData();
}
IEnumerator FadeInCharacter(int index, float duration = 0.5f)
{
if (duration <= 0)
{
SetSingleCharacterAlpha(index, 255);
}
else
{
float timer = 0;
while (timer < duration)
{
timer = Math.Min(timer + Time.unscaledDeltaTime, duration);
SetSingleCharacterAlpha(index, (byte)(timer / duration * 255));
yield return null;
}
}
}
}
?