功能:
1.文字逐个出现
2.支持富文本
3.添加<float>标签可以延迟显示
4.想快速展示完调用函数 ImmediatelyShow
准备:
代码:
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; } } } }