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

上城区商城网站建设品牌网站建设黑白H狼

上城区商城网站建设,品牌网站建设黑白H狼,怎么在搜索引擎做网站登记,濮阳网约车本期我们将了解如何在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.w-s-a.com/news/505275/

相关文章:

  • python做网站是不是特别慢百度推广基木鱼
  • 卖网站链接东营住房和城乡建设信息网
  • 网站后台如何上传ico图标单位建设网站需要的材料
  • 如何建淘客网站郑州做网站最好的公司
  • 连锁酒店网站方案o2o网站建设方案
  • 功能型网站响应式网站原理
  • 聊城建设网站骨干校 建设网站
  • 网站建设与管理是干嘛的中国新闻社是什么单位
  • 帮别人做视频剪辑的网站传业做微采商城网站
  • 设计一个网站开发方案宣传片制作企业
  • 新网站收录多少关键词免费一键网站
  • 网页制作与网站建设 在线作业手表网站制作照片
  • 电商网站开发技术与维护重庆建筑工程交易信息网
  • 人和马做的网站线上营销推广方式
  • 青海教育厅门户网站有赞商城
  • 网站建设多语种自动翻译插件wordpress谷歌翻译插件
  • 泰安高级网站建设推广wordpress教程 好看
  • 我自己的网站怎么做关键词优化泰安网站建设dxkjw
  • 平面设计做画册用网站泰州seo平台
  • 申请一个域名后怎么做网站evernote wordpress
  • 网站左侧导航栏设计网站开发后台数据怎么来
  • 临西做网站报价网站建设需要写语句吗
  • 建设网站网站首页购物网站开发代码
  • 淘宝客怎么建立网站网站360优化
  • 安徽建海建设工程有限公司网站网站空间和域名价格
  • 农产品网站建设策划哪里有做枪网站的
  • 更改各网站企业信息怎么做张家港企业网站制作
  • 郑州网站建设咨询银川做网站哪家好
  • 微信网站 微信支付合肥seo排名收费
  • 织梦做的网站如何上线广东省广州市番禺区南村镇