前段时间需要做一个打字机效果的案子,网上也有很多UGUI的打字机插件,利用tweener动画制作的。不过后来我发现很多都不默认支持富文本,所以需要自己改写代码。这里我简化了代码,做了一个精简版的打字机效果。
必须有GIF

TypewriterEffect组件代码如下:

using UnityEngine;
using System.Text;
using System.Collections.Generic;
using UnityEngine.Events;
using UnityEngine.UI;
using DG.Tweening;
using System.Text.RegularExpressions;/// <summary>
/// This script is able to fill in the text's text gradually, giving the effect of someone typing or fading in the content over time.
/// </summary>public class TypewriterEffect : MonoBehaviour
{public string val;/// <summary>/// How many characters will be printed per second./// </summary>public int charsPerSecond = 20;/// <summary>/// How long it takes for each character to fade in./// </summary>public float delayOnSpace = 1f;/// <summary>/// Event delegate triggered when the typewriter effect finishes./// </summary>public UnityEvent onFinished = new UnityEvent();private Tweener doFadeTweener;Text mLabel;string mFullText = "";int mCurrentOffset = 0;float mNextChar = 0f;bool mReset = false;bool mActive = false;/// <summary>/// Whether the typewriter effect is currently active or not./// </summary>public bool isActive { get { return mActive; } }public bool isComplete = true;public void WordByWord(string content){QuickShow();isComplete = false;val = content;mReset = true;mActive = true;}//在逐渐显示的时候点击对话,快速显示所有文字//重复QuickShow不会重复触发onFinishpublic void QuickShow(){//结束淡入淡出if (doFadeTweener != null)doFadeTweener.Kill(true);else{//结束WordByWordmReset = false;Finish();}}/// <summary>/// Finish the typewriter operation and show all the text right away./// </summary>public void Finish(){if (mActive){mActive = false;if (!mReset){mCurrentOffset = mFullText.Length;mLabel.text = val;}onFinished.Invoke();}}private void Awake(){//onFinished.AddListener(() => Debug.LogError("Finish!"));mLabel = GetComponent<Text>();mLabel.text = "";onFinished.AddListener(() => isComplete = true);}Regex tagPattern = new Regex("<[^>]*>[^<]*</[^>]*>");Regex contPattern = new Regex(">.*<");private StringBuilder sb;private Dictionary<int, cont> realPosList = new Dictionary<int, cont>();class cont{public int realIdx;public bool bCont;public string endStr;public cont(int realIdx, bool bCont = false, string endStr = "</color>"){this.realIdx = realIdx;this.bCont = bCont;this.endStr = endStr;}}cont GetRealIndex(int index){cont value;if (realPosList.TryGetValue(index, out value)){return value;}return new cont(index);}string ReplaceCharInTag(string lastText){sb = new StringBuilder();realPosList.Clear();var group = tagPattern.Matches(lastText);var startIndex = 0;if (group.Count > 0){for (int i = 0; i < group.Count; i++){var m1 = group[i];for (int j = startIndex; j < m1.Index; j++){realPosList.Add(sb.Length, new cont(j));sb.Append(lastText[j]);}startIndex = m1.Index + m1.Length;var m2 = contPattern.Match(m1.Value);if (m2.Success){for (int k = 1; k < m2.Value.Length - 1; k++){realPosList.Add(sb.Length, new cont(m1.Index + m2.Index + k, true));sb.Append(m2.Value[k]);}}if (i == group.Count - 1){for (int j = startIndex; j < lastText.Length; j++){realPosList.Add(sb.Length, new cont(j));sb.Append(lastText[j]);}}}}else{return lastText;}return sb.ToString();}void Update(){if (!mActive) return;if (mReset){mNextChar = 0;mLabel.text = "";mCurrentOffset = 0;mReset = false;if (mLabel.supportRichText){mFullText = ReplaceCharInTag(val);}else{mFullText = val;}}while (mCurrentOffset < mFullText.Length && mNextChar <= Time.unscaledTime){int lastOffset = mCurrentOffset;charsPerSecond = Mathf.Max(1, charsPerSecond);// Automatically skip all symbolswhile (ParseSymbol(mFullText, ref mCurrentOffset)) { }++mCurrentOffset;// Periods and end-of-line characters should pause for a longer time.float delay = 1f / charsPerSecond;char c = (lastOffset < mFullText.Length) ? mFullText[lastOffset] : '\n';if (c == ' ')delay += delayOnSpace;if (mNextChar == 0f){mNextChar = Time.unscaledTime + delay;}else mNextChar += delay;if (mLabel.supportRichText){cont ct = GetRealIndex(mCurrentOffset - 1);mLabel.text = val.Substring(0, ct.realIdx + 1) + (ct.bCont ? ct.endStr : "");}else{mLabel.text = mFullText.Substring(0, mCurrentOffset); ;}}if (mCurrentOffset == mFullText.Length){onFinished.Invoke();mActive = false;}}/// <summary>/// Parse an embedded symbol, such as [FFAA00] (set color) or [-] (undo color change). Returns whether the index was adjusted./// </summary>static public bool ParseSymbol(string text, ref int index){int length = text.Length;if (index + 17 > length || text[index] != '<' || text[index + 16] != '>') return false;if (text[index + 1] == '/') return false;if (!text.Substring(index, 8).Equals("<color=#")) return false;string alpha = text.Substring(index + 14, 2);int a = (HexToDecimal(alpha[0]) << 4) | HexToDecimal(alpha[1]);index += 17;return true;}static public int HexToDecimal(char ch){switch (ch){case '0': return 0x0;case '1': return 0x1;case '2': return 0x2;case '3': return 0x3;case '4': return 0x4;case '5': return 0x5;case '6': return 0x6;case '7': return 0x7;case '8': return 0x8;case '9': return 0x9;case 'a':case 'A': return 0xA;case 'b':case 'B': return 0xB;case 'c':case 'C': return 0xC;case 'd':case 'D': return 0xD;case 'e':case 'E': return 0xE;case 'f':case 'F': return 0xF;}return 0xF;}
}

核心在于如何处理富文本的地方,我这里使用最简单的字符串匹配模式,将富文本的地方打标记。在Update时。获取实际打标记的index。同时判断是否在富文本的区间,自动补全结束的标签。当然,我这里给出的只支持颜色打字机效果,有需求的可以将代码中的endStr参数也赋值即可,如果后期有项目需求做以及更多的富文本的话,会继续改善代码。
下面附上demo
//download.csdn.net/download/weixin_43876382/12010790

Unity之富文本打字机效果相关推荐

  1. Unity Text富文本(文本变得多姿多彩)

    Unity Text富文本(文本变得多姿多彩) 实例: 步骤如下: 1.创建一个UI Text 2.Text组件中的Rich Text要勾选上 3.写内容 html控制代码 实例: 步骤如下: 1.创 ...

  2. Android使用Kotlin加协程实现文本打字机效果

    文字显示效果自己脑补:头疼,产品提了个需求,要求富文本展示,欧克好了!过了几天又要求实现打字机效果 一.我的实现: /*** 普通文本实现打字机效果** // In an Activity: myTe ...

  3. 【实战】用CSS实现文本打字机效果

    之前,我们的文章中已经有通过 JS 的方式实现文本打字机的效果了,具体可以看这篇文章: [前端三分钟]利用Javascript实现打字效果 在本文中,你将学习如何使用纯CSS实现打字机效果,使网站的文 ...

  4. [Unity][FairyGUI]富文本改变颜色

    在FGUI编辑器中 设置了之后才可以 ... using FairyGUI; ... GTextFiled text1; ...text1.text = "测试[color=#123456] ...

  5. 如何扩展Android富文本之Html标签

    前言 大家都知道Android 富文本其实就是HTML标签那些东西,但Android本身对其支持有限,今天就说说如何对其进行扩展 富文本 在Android设置富文本一般如下 String txt = ...

  6. dj电商-富文本编辑器

    tinymce 安装 下载好后按步骤来操作 注册 配置富文本编辑器 3 在项目中配置路由 开始使用,模型类中导入 >先导入,再使用 查看效果 >在后台管理模块中注册 >商品状态,是可 ...

  7. 使用UIWebView中html标签显示富文本

    使用UIWebView中html标签显示富文本 用UIWebView来渲染文本并期望达到富文本的效果开销很大哦! Work 本人此处直接加载自定义字体"新蒂小丸子体",源码不公开, ...

  8. C语言对文本进行断句,用TextView实现富文本展示,点击断句和语音播报

    最近有一个需求:移动端需要展示用户在PC端做的笔记,而笔记内容是富文本形式--有图片,有文字,文字可以设置颜色.加粗.倾斜等等.同时,用户点击的时候能够语音朗读所点击的当前整句的内容. 第一反应就是富 ...

  9. 富文本编辑器Quill 介绍及在Vue中的使用方法

    在Web开发中,富文本编辑器是不可或缺的一个功能组件,掌握少量基础语法就能让一篇文章实现较为不错的排版效果,即见即所得. 目前市场上已提供大量集成富文本编辑器的包,Quill 作为其中一个,以简单.易 ...

最新文章

  1. 怎么在vs2010中使用ActiveX Test Container(转)
  2. 恩布企业即时通讯软件,EntboostChat 1.4.2发布,iOS开源IM
  3. 利用FreeNas创建WebDAV共享并实现ssl加密
  4. 死磕Java并发:J.U.C之AQS:CLH同步队列
  5. 新思科技助力IBM将AI计算性能提升1000倍
  6. setxor--求两个集合交集的非(异或)
  7. IDEA2017注册码
  8. jsp mysql在线考试系统源码_jsp+ssm+mysql实现的学生在线考试系统项目源码附带视频导入运行教程...
  9. 安卓系统手机软件_2M不到的安卓神器!有了这五款软件,iphone用户都羡慕
  10. linux 安装rpm qt can't creat,CentOS 6.2部署Qt开发环境
  11. 赛锐信息:SAP ABAP 屏幕导航
  12. 论文笔记_S2D.33_2015-ICCV_使用单个多尺度卷积网络,预测深度、表面法线和语义标签
  13. vim 查找相同行 删除向同行
  14. 怎么解Linux内核温控,Linux Thermal 框架解析
  15. Java面试中如何介绍自己的项目经验?
  16. win10更改/修改c盘下的用户名/Users
  17. java 查看堆内存_查看java内存情况的几个常用命令
  18. 六, 跨语言微服务框架 - Istio Ingress和Egress详解(解决Istio无法外网访问问题)
  19. eclipse绿色版
  20. 【单片记笔记】基于STM32F103的NEC红外发送接收使用同一个定时器的一体设计

热门文章

  1. 考研英语——单词和语法
  2. 反向题在测试问卷信效度_问卷信效度分析
  3. Ghost安装windows系统出现A:\GHOSTERR.TXT的解决办法
  4. 沉睡者-程序员利用javascript开发捕鱼达人游戏
  5. 请求(request)
  6. 光线折射模拟的matlab仿真
  7. Vue中demo@0.1.0 serve `vue-cli-service serve`解决方法
  8. 移动开发技术新趋向(二)
  9. HDOJ -- 1285 确定比赛名次
  10. python代码库能干什么_一行Python代码能做什么?