当前位置: 首页 > news >正文

做一个企业网站花费济南网络安全公司

做一个企业网站花费,济南网络安全公司,技术交流网站开发例子,wordpress 作者昵称本期我们将了解如何在TMPro中自定义我们的标签样式#xff0c;并实现两种有趣的效果。 一.需求描述 1.定义float格式的标签#xff0c;实现标签处延迟打印功能 2.定义r /r格式的标签#xff0c;实现标签区间内文本片段的注释显示功能…本期我们将了解如何在TMPro中自定义我们的标签样式并实现两种有趣的效果。 一.需求描述 1.定义float格式的标签实现标签处延迟打印功能 2.定义r /r格式的标签实现标签区间内文本片段的注释显示功能 3.补充文本多种打印样式功能。 二.自定义标签样式 首先我们需要借助预处理器来读取到我们的目标格式的标签并记录标签内的相关信息 基本思路通过ITextPreprocessor接口实现预处理器的预加工函数PreprocessText读取到文本中的自定义标签格式并记录标签内信息。 1.实现接口方法 public class AdvancedTextPreprocessor : ITextPreprocessor{public string PreprocessText(string text){}} 2.提取标签 1使用正则表达式来匹配的类html格式。 public string PreprocessText(string text){string processingText text;string pattern .*?;//定义一个正则表达式 .* 用于匹配所有以 开头、 结尾的字符串。贪婪模式即它会匹配最远的 Match match Regex.Match(processingText, pattern);//首次匹配查找所有富文本标签while (match.Success) //尝试匹配富文本标签{match Regex.Match(processingText, pattern);//继续匹配查找下一个标签}processingText text;return processingText; }//正则表达式概念// . 代表任意字符//*代表前一个字符出现0次或多次//代表前一个字符出现1次或多次//代表前一个字符出现0次或1次 这里我们定义了.*这种文本模式,下方代码将在用户文本中查找符合模式的文本片段match。 Match match Regex.Match(processingText, pattern);//按照pattern模式来匹配用户文本中符合格式的文本含 3.记录标签内信息 下面我们需要记录下我们的自定义标签内的信息。 1.定义存储结构 /// summary /// 打印延迟字典【读取标签float,遇到将延迟float秒后打印后面内容】 /// /summary public Dictionaryint, float IntervalDictionary new Dictionaryint, float();//自定义打印标签字典/// summary /// 注释标签列表 /// /summary public ListRubyData rubyList new ListRubyData(); 这里我使用字典存储延迟标签信息将延迟标签的位置偏移作为键延迟长度作为值。 使用列表来存储注释数据结构。成员是Rubydata类的实例。 Rubydata类中定义了3种属性注释自身在文本中的起止位置偏移startIndex和终止位置偏移endIndex,以及注释内容contnet。 RubyData类如下 /// summary/// 注释数据/// /summarypublic class RubyData{public RubyData(int _startIndex, string _content){startIndex _startIndex;rubyContent _content;}public int startIndex { get; }public string rubyContent { get; }public int endIndex { get; set; }} 2.匹配标签内的文本信息 下方代码功能是去除match文本中包含的字符得到标签内的信息label。 string label match.Value.Substring(1, match.Length - 2); 3.标签内信息的存储逻辑 1读取float格式标签内容 //自定义延迟打印标签【规定float】并记录在打印间隔标签字典中if (float.TryParse(label, out float result))IntervalDictionary[match.Index - 1] result; 此处由于标签内部就是一个float类型的数据所以我们可以直接就爱那个标签记录在我们的打印间隔标签字典中 2读取r /r格式标签内容 //自定义注释标签【规定r】录入注释列表//注释标签开启if (Regex.IsMatch(label, ^r.)) //^表示字符串的开头。这个符号确保匹配的字符串必须从开头开始rubyList.Add(new RubyData(match.Index, label.Substring(2)));//注释标签终止else if (Regex.IsMatch(label, /r)){if (rubyList.Count 0)rubyList[rubyList.Count - 1].endIndex match.Index - 1;} 4.去除标签文本 由于我们在用户文本中含有的类html标签但是最终是不需要显示的所以我们还需要在用户文本的基础上去除我们的标签(替换为空字符串)才能得到最终的渲染文本。 pattern ((\d)(\.\d)?)|(/r)|(r.*?);//使用 前缀可以避免在字符串中使用转义字符//将处理文本中符合pattern规则的字符串 替换为空字符串processingText Regex.Replace(processingText, pattern, ); 完整源码见后文。 三.实现自定义文本效果 1.延迟打印功能 现在我们已经可以存储文本中的自定义标签内的信息我们现在来实现一下文本的自定义效果。 我们前面已经实现了打字机的效果实际上的延时打印功能就是在打字函数的携程循环中等待的迭代函数。 if (selfPreprocessor.IntervalDictionary.TryGetValue(typingIndex, out float result))yield return new WaitForSecondsRealtime(result);elseyield return new WaitForSecondsRealtime(defalutInterval); 上句代码用来判断文本中当前打印位置处会否是延迟标签所在位置。如果恰好是字典中延迟标签的位置则返回字典中的的当前位置键对应的float值作为输入执行携程延迟函数。否则按照默认间隔执行打印延迟。 2.注释功能 我们具体会用到两个方法。 1生成并设置注释 void SetRubyText(RubyData data) {GameObject ruby Instantiate(Resources.LoadGameObject(RubyText), transform);ruby.GetComponentTextMeshProUGUI().SetText(data.rubyContent);ruby.GetComponentTextMeshProUGUI().color textInfo.characterInfo[data.startIndex].color;ruby.transform.localPosition (textInfo.characterInfo[data.startIndex].topLeft textInfo.characterInfo[data.endIndex].topRight) / 2 - new Vector3(0, 10, 0); } 这里我们传入一个Rubydata实例设置预制件文本颜色及位置。 2判断当前位置是否是注释的起始位 /// summary/// 读取一个位置是否就是Ruby起始位/// /summary/// param nameindex/param/// param namedata/param/// returns/returnspublic bool TryGetRubyText(int index, out RubyData data){data new RubyData(0, );foreach (RubyData item in rubyList){if (item.startIndex index){data item;return true;}}return false;} } 每打印到一个位置我们都需要判断当前位置是否是注释标签的起始位。如果是将调用生成注释预制件的函数。 四.改进文本显示逻辑 现在我们去AdvancedText类中改进一下前面实现的文本显示逻辑。 增添字段 Coroutine typingCor;//存储打字携程易于中断Action OnFinish; //文本打印结束的回调委托 这里的携程字段使用来记录我们的打字机携程的实际情况中我们会遇到 打断正在打印中文本 的需求。存储到一个携程变量中将易于管理。 增添枚举 我们使用一个枚举来决定文本以什么形式显示。见下方 public enum E_DisplayType {Defalut,Fading,Typing }Defalut模式文本采用 整体直接显示。 Fading模式文本采用 整体淡入显示。 Typing模式文本采用 打字机淡入效果显示。 我们现在实现一下各种打印样式的函数。 Defalut模式显示方法 /// summary/// 文本整体直接显示/// /summaryvoid DefalutDisplay(Action action null){for (int i 0; i m_characterCount; i)SetSingleCharacterAlpha(i, 255);action?.Invoke();} Fading模式显示方法 /// summary/// 文本整体淡入显示/// /summaryvoid FadingDisplay(float fadeDuration,Action actionnull){for (int i 0; i m_characterCount; i)StartCoroutine(FadeInCharacter(i, fadeDuration));action?.Invoke();} Typing模式显示方法 /// summary/// 文本打字机显示/// /summary/// returns/returnsIEnumerator TypingDisplay(float fadeDuration,Action action null){ForceMeshUpdate();for (int i 0; i m_characterCount; i){SetSingleCharacterAlpha(i, 0);}typingIndex 0;while (typingIndex m_characterCount){//SetSingleCharacterAlpha(typingIndex,255); //无淡入打字机效果StartCoroutine(FadeInCharacter(typingIndex, fadeDuration)); //淡入打字机效果if (selfPreprocessor.IntervalDictionary.TryGetValue(typingIndex, out float result))yield return new WaitForSecondsRealtime(result);elseyield return new WaitForSecondsRealtime(defalutInterval);typingIndex;}action?.Invoke();} 文本显示方法 我们还需要一个函数作为暴露给外部的应用接口客户端可以选择不同的文本显示样式。 public IEnumerator ShowText(string content, E_DisplayType displayType, float duration){if (typingCor ! null){StopCoroutine(typingCor);}typingCor null;SetText(content);yield return null;TextDisAppear();switch (displayType){case E_DisplayType.Defalut:DefalutDisplay();SetAllRubyTexts();break;case E_DisplayType.Fading:FadingDisplay(duration);SetAllRubyTexts();break;case E_DisplayType.Typing:typingCor StartCoroutine(TypingDisplay(duration));break;default:break;}} 五.功能测试 在测试脚本中我们调用AdvancedText实例的携程来显示文本。 StartCoroutine(advancedText.ShowText(content,displayType,duration)); 编辑器内选择打印样式。 运行效果 这里我是做了一个按键输入功能通过按键显示并开始打印文本但调用文本打印的逻辑是一致的。如果大家对UI动效有有兴趣的话我后面可以出一期关于UI的代码框架及动效功能的解决方案。 六.完整源码 AdvancedTextPreprocessor类   using System.Collections.Generic; using System.Text.RegularExpressions; using TMPro;namespace DialogueDemo {public class AdvancedTextPreprocessor : ITextPreprocessor{/// summary/// 打印延迟字典【读取标签float,遇到将延迟float秒后打印后面内容】/// /summarypublic Dictionaryint, float IntervalDictionary new Dictionaryint, float();//自定义打印标签字典public ListRubyData rubyList new ListRubyData();public string PreprocessText(string text){IntervalDictionary.Clear();string processingText text;string pattern .*?;//定义一个正则表达式 .* 用于匹配所有以 开头、 结尾的字符串。贪婪模式即它会匹配最远的 Match match Regex.Match(processingText, pattern);//首次匹配查找所有富文本标签while (match.Success) //尝试匹配富文本标签{string label match.Value.Substring(1, match.Length - 2);//自定义延迟打印标签【规定float】并记录在打印间隔标签字典中if (float.TryParse(label, out float result))IntervalDictionary[match.Index - 1] result;//自定义注释标签【规定r】录入注释列表//注释标签开启else if (Regex.IsMatch(label, ^r.)) //^表示字符串的开头。这个符号确保匹配的字符串必须从开头开始rubyList.Add(new RubyData(match.Index, label.Substring(2)));//注释标签终止else if (Regex.IsMatch(label, /r)){if (rubyList.Count 0)rubyList[rubyList.Count - 1].endIndex match.Index - 1;}processingText processingText.Remove(match.Index, match.Length);//读取此打印间隔标签后删除此标签if (Regex.IsMatch(label, ^sprite.)) //如果标签格式是精灵需要一个占位符processingText.Insert(match.Index, *);match Regex.Match(processingText, pattern);//继续匹配查找下一个标签}processingText text;//正则表达式概念// . 代表任意字符//*代表前一个字符出现0次或多次//代表前一个字符出现1次或多次//代表前一个字符出现0次或1次pattern ((\d)(\.\d)?)|(/r)|(r.*?);//使用 前缀可以避免在字符串中使用转义字符//简单解释本句代码实现了读取中的整数或小数的功能/* (\d )\d 是一个数字匹配模式它匹配一个或多个数字字符。表示前面的模式数字可以匹配一个或多个字符。() 是捕获组的标记这样 \d 匹配到的数字部分就会被捕获到组中可以在后续处理中使用。(\.\d )?\. 匹配一个字面上的点.。点号是一个元字符在正则中表示任意字符但在这里需要加 \ 进行转义表示字面上的点号。\d 匹配一个或多个数字表示小数点后面的部分。() ? 表示这个捕获组是可选的即小数部分不是必需的。如果没有小数部分这一部分会被忽略。*///将处理文本中符合pattern规则的字符串 替换为 后面的字符串processingText Regex.Replace(processingText, pattern, );return processingText;}/// summary/// 读取一个位置是否就是Ruby起始位/// /summary/// param nameindex/param/// param namedata/param/// returns/returnspublic bool TryGetRubyText(int index, out RubyData data){data new RubyData(0, );foreach (RubyData item in rubyList){if (item.startIndex index){data item;return true;}}return false;}}/// summary/// 注释数据/// /summarypublic class RubyData{public RubyData(int _startIndex, string _content){startIndex _startIndex;rubyContent _content;}public int startIndex { get; }public string rubyContent { get; }public int endIndex { get; set; }} } AdvancedText类 using System; using System.Collections; using TMPro; using UnityEngine;namespace DialogueDemo {public class AdvancedText : TextMeshProUGUI{int typingIndex;float defalutInterval 0.08f;Coroutine typingCor;//存储打字携程易于中断Action OnFinish;AdvancedTextPreprocessor selfPreprocessor (AdvancedTextPreprocessor)textPreprocessor;private void Init(){SetText();ClearRubyText();}public AdvancedText(){textPreprocessor new AdvancedTextPreprocessor();}public void TextDisAppear(){for (int i 0; i m_characterCount; i)SetSingleCharacterAlpha(i, 0);}public IEnumerator ShowText(string content, E_DisplayType displayType, float duration){if (typingCor ! null){StopCoroutine(typingCor);}typingCor null;SetText(content);yield return null;TextDisAppear();switch (displayType){case E_DisplayType.Defalut:DefalutDisplay();SetAllRubyTexts();break;case E_DisplayType.Fading:FadingDisplay(duration);SetAllRubyTexts();break;case E_DisplayType.Typing:typingCor StartCoroutine(TypingDisplay(duration));break;default:break;}}/// summary/// 直接显示/// /summaryvoid DefalutDisplay(Action action null){for (int i 0; i m_characterCount; i)SetSingleCharacterAlpha(i, 255);action?.Invoke();}/// summary/// 整体淡入/// /summaryvoid FadingDisplay(float fadeDuration,Action actionnull){for (int i 0; i m_characterCount; i)StartCoroutine(FadeInCharacter(i, fadeDuration));action?.Invoke();}/// summary/// 打字机显示/// /summary/// returns/returnsIEnumerator TypingDisplay(float fadeDuration,Action action null){ForceMeshUpdate();for (int i 0; i m_characterCount; i){SetSingleCharacterAlpha(i, 0);}typingIndex 0;while (typingIndex m_characterCount){//SetSingleCharacterAlpha(typingIndex,255); //无淡入打字机效果StartCoroutine(FadeInCharacter(typingIndex, fadeDuration)); //淡入打字机效果if (selfPreprocessor.IntervalDictionary.TryGetValue(typingIndex, out float result))yield return new WaitForSecondsRealtime(result);elseyield return new WaitForSecondsRealtime(defalutInterval);typingIndex;}action?.Invoke();}/// summary/// 设置单字符的透明度每个字符都是由网格含4个顶点渲染/// /summary/// param nameindex/param/// param namenewAlphanewalpha范围为0~255/paramvoid SetSingleCharacterAlpha(int index, byte newAlpha){TMP_CharacterInfo character textInfo.characterInfo[index];//获取文本内容索引下的单个字符if (!character.isVisible)return;int matIndex character.materialReferenceIndex;//获取字符材质索引int vertexIndex character.vertexIndex;//获取字符顶点索引for (int i 0; i 4; i){textInfo.meshInfo[matIndex].colors32[vertexIndex i].a newAlpha;}UpdateVertexData();//更新顶点数据}/// summary/// 单字符淡入/// /summary/// param nameindex/param/// param nameduration/param/// returns/returnsIEnumerator FadeInCharacter(int index, float duration){//如果找到Ruby起始位设置Ruby预制件Debug.Log(selfPreprocessor.TryGetRubyText(index, out var data1));if (selfPreprocessor.TryGetRubyText(index, out RubyData data))SetRubyText(data);if (duration 0)SetSingleCharacterAlpha(index, 255);else{float timer 0;while (timer duration){timer Mathf.Min(duration, timer Time.unscaledDeltaTime);SetSingleCharacterAlpha(index, (byte)(255 * (timer / duration)));yield return null;}}}void SetRubyText(RubyData data){GameObject ruby Instantiate(Resources.LoadGameObject(RubyText), transform);ruby.GetComponentTextMeshProUGUI().SetText(data.rubyContent);ruby.GetComponentTextMeshProUGUI().color textInfo.characterInfo[data.startIndex].color;ruby.transform.localPosition (textInfo.characterInfo[data.startIndex].topLeft textInfo.characterInfo[data.endIndex].topRight) / 2 - new Vector3(0, 10, 0);}/// summary/// 清除当前的所有注释/// /summaryvoid ClearRubyText(){foreach (var item in GetComponentsInChildrenTextMeshProUGUI()){if (item ! this)Destroy(item.gameObject);}}/// summary/// 用于跳过对话直接显示所有注释/// /summaryvoid SetAllRubyTexts(){foreach (var item in selfPreprocessor.rubyList){SetRubyText(item);}}} }七.尾声 在 Unity 的 TextMeshPro中文本标签如 colorred.../color的处理方式不同于我们在自定义 AdvancedTextPreprocessor 类中的实现。TextMeshPro 之所以能正确处理 colorred /color 等标签原因在于它内部已经预先实现了一个功能强大的解析器用于识别和处理各种富文本标签。TMP处理这些标签的方法是通过其 TextParser 类内部的规则和机制。具体的实现位于 TextMeshPro 的源码中这些规则和方法是在 TextMeshPro 的组件中预定义的。当你将含有富文本标签的字符串传递给 TMP_Text 组件时TextMeshPro 会自动解析这些标签并应用对应的样式。这与 AdvancedTextPreprocessor 类不同后者是我们自己实现的自定义处理器它仅仅处理我们通过正则表达式解析并手动处理的标签例如延迟打印标签、注释标签等并不会干预 TextMeshPro 内部已经定义的标准标签处理。 本篇完
http://www.dnsts.com.cn/news/31687.html

相关文章:

  • 一个网站怎么做2个服务器微信小程序成本
  • 邯郸做移动网站价格表wordpress伪静态教程
  • 长沙私人做网站虚拟主机网站淘客网站建设
  • 跨境电商发展现状如何新网站排名优化怎么做
  • 网站静态页面模板网站建设费用怎么入账
  • 网站做下载功能艺术字体在线生成器英文
  • 深圳 网站制作 哪家wordpress获取自定义字段的值
  • 地方网站类型在线crm视频
  • 网站前端跟后端怎么做怎么查名字有没有被注册商标
  • 中山网站建设公司哪家好phpcms 做购物网站
  • 怎样把自己的网站进行推广wordpress评论者名字
  • 苏州营销型网站开发公司外贸seo优化公司
  • hao123网站难做吗国内有wix做的好的网站
  • 香橼做空机构网站架设网站的目的
  • 中山做网站的公司胶州建设局网站
  • 深圳外贸网站推广六盘水建设网站
  • 电商网站建设案例怎么建设网站页面
  • lamp网站开发黄金组合制作网站后台
  • 网站建设开始学什么美食网站策划书范文
  • 毕业设计做旅游网站合肥网站建设模板
  • 帝国 cms 网站关键字wordpress使用缩略图
  • 一个网站需要多少空间网站建设首选定制开发
  • 专业合肥网站建设中山网站快照优化公司
  • 网站栏目建设评活动企业建站平台哪个好
  • 网站关键词的使用成都柚米科技公众号开发
  • 南京房产网站建设珠宝怎么做网站
  • 国家住房城乡建设部网站我是做废品回收,最近有个变宝网主动联系我说是再生资源网站的,可信吗?
  • 仿站定制模板建站seo平台优化
  • 网站建设 个人潍坊网站建设尚荣
  • 德州定制网站建设公司柳州 网站开发