样式
例:
1.<style=H1>
Hellow <style=H1>world 效果:
样式表
路径:
插入图片
插入默认图片
2.<sprite=0>
text<sprite=0> 效果:
图集路径:
导入单个图片
给png图片添加精灵资产
inde为0
因为用到了动态加载,所以一定要把常见的资产放在Resources文件夹下
导入多图片
先在包管理器中找到2D Sprite导入
切片完以后再创建精灵
设置默认图集
修改此处
修改图片坐标
在图片集中修改
代码的修改
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using System.Text.RegularExpressions;
using System;
/// <summary>
/// 增加文本时间停顿功能
/// 增加文字渐出,(单个字符逐渐显现)
/// </summary>
//文本时间停顿功能
//效果:如果使用AdvancedTextPreprocessor的预处理器
//则先经过string ITextPreprocessor.PreprocessText(string text)该方法处理的返回值
//才能显示出来
public class AdvancedTextPreprocessor : ITextPreprocessor
{
//字典类型,表示在第几个字后面停顿的时间
public Dictionary<int, float> InterrvalDictionary;
public AdvancedTextPreprocessor()
{
InterrvalDictionary=new Dictionary<int, float>();
}
public string PreprocessText(string text)
{
//清空字典
InterrvalDictionary.Clear();
string processingText=text;
//.:任意字符,*:匹配前面的字符零次或者多次,?:匹配最近的结果
//*?匹配零次或者多次的那个最短的结果
string pattern = "<.*?>";
//输入的字符串+以那种规则去匹配的字符串
Match match= Regex.Match(processingText,pattern);
//删掉所有标签
//如果可以匹配到结果
while(match.Success)
{
string label = match.Value.Substring(1,match.Length - 2);
//如果能转换为浮点类型则进入if,结果存到 result中
if (float.TryParse(label,out float result))
{
//因为<0.3>前面还有<占一个位置
InterrvalDictionary[match.Index - 1] = result;
}
//删掉标签
processingText = processingText.Remove(match.Index, match.Length);
//^表示必须从字符串的开头进行匹配
if (Regex.IsMatch(label, "^sprite=.+"))
{
processingText = processingText.Insert(match.Index, "*");
// processingText = processingText.Remove(match.Index, match.Length);
}
match = Regex.Match(processingText,pattern);
}
//删掉数据标签
processingText = text;
//* 代表前一个字符出现零次或多次
//+ 代表前一个字符出现一次或多次
//? 代表前一个字符出现零次或一次
//. 代表任意字符
pattern = @"<(\d+)(\.\d+)?>";
//processingText中,把所有符合pattern规则的字符替换成"xxx"
processingText = Regex.Replace(processingText, pattern, "");
return processingText;
}
}
public class AdvancedText : TextMeshProUGUI
{
public AdvancedText()
{
//接口类型的预处理器textPreprocessor(可以自己定义预处理效果是什么样的)
textPreprocessor = new AdvancedTextPreprocessor();
}
private AdvancedTextPreprocessor SelfPreprocessor => (AdvancedTextPreprocessor)textPreprocessor;
public void ShowTextByTyping(string content)
{
SetText(content);
StartCoroutine(Typing());
}
private int _typingIndex;
private float _defaultInterval = 0.06f;
IEnumerator Typing()
{
//强制网格更新
ForceMeshUpdate();
for (int i = 0; i < m_characterCount; i++)
{
//先把颜色设置成透明
SetSingleCharacterAlpha(i, 0);
}
_typingIndex = 0;
while (_typingIndex < m_characterCount)
{
if (textInfo.characterInfo[_typingIndex].isVisible)
{
StartCoroutine(FadeInCharacter(_typingIndex));
}
//SetSingleCharacterAlpha(_typingIndex, 255);
if (SelfPreprocessor.InterrvalDictionary.TryGetValue(_typingIndex, out float result))
{
yield return new WaitForSecondsRealtime(result);
}
else
{
yield return new WaitForSecondsRealtime(_defaultInterval);
}
_typingIndex++;
}
//yield return null;
}
//原理:改变单个文字的Alpha
//newAlpha范围是0-255
private void SetSingleCharacterAlpha(int index, byte newAlpha)
{
TMP_CharacterInfo charInfo = textInfo.characterInfo[index];
//材质索引
int matIndex = charInfo.materialReferenceIndex;
//顶点索引
int verIndex = charInfo.vertexIndex;
for (int i = 0; i < 4; i++)
{
//color32表示所有的顶点颜色
textInfo.meshInfo[matIndex].colors32[verIndex + i].a = newAlpha;
}
UpdateVertexData();
}
// 渐显角色函数,用于平滑地调整角色透明度
IEnumerator FadeInCharacter(int index, float duration = 0.2f)
{
//瞬间显示
if (duration <= 0)
{
SetSingleCharacterAlpha(index, 255);
}
else
{
float timer = 0;
while(timer<duration)
{
//unscaledDeltaTime不考虑时间的放缩,游戏暂停的时候也不停止
//timer不能超过duration
timer = Mathf.Min(duration, timer + Time.unscaledDeltaTime);
SetSingleCharacterAlpha(index, (byte)(255 * timer / duration));
yield return null;
}
}
}
}