感受使用Unity以后总能看到各类各样解决混排的方案,只能说明Unity不够体恤下情啊。这篇文章主要讲一下我的在使用过程当中方案选择和优化过程,已作记录。顺便提下,开源不少意味着坑,仍是要开实际需求。html
1 TextMeshPro
Unity 最近公布收购了TextMeshPro而且免费开源给你们使用,估计还须要几个小版本才会彻底融合到Unity中或者保持如今的状态。TextMeshPro支持效果丰富,兼容如今UI层级等,性能也能够知足移动端,可是很纠结的是:git
基于上面亮点,最后我仍是没有采用这种方案,若是Unity考虑融合进来,建议修改下字库的使用方式。github
2 文字和图片独立渲染编程
最后采用了文字富文本保留空间,图片根据位置单独渲染的方案,主要的缘由在于性能可控以及如今代码还算比较完善(这里彻底是个坑)。这个版本最初的源码:https://code.csdn.net/qq992817263/uguitextpro/tree/master缓存
2.1 基本思想数据结构
参考文章
Unity Text 插入图片,这篇文章是基本的实现方式,后面CSDN“神码编程”也就在这基础上作了几处扩展和一些文章分享编辑器
2.2 代码实现思路测试
提早生成sprite区域信息,若是是一个系列的表情则根据sprite名字进行区分,固然后面也根据名字进行保留和查找。如angry_0\angry_1\angry_2\angry_3 , die_0/die_1/die_2/die_4/die_5/die_6字体
继承Text组件,重写OnPopulateMesh以及字符解析,维护里面图片位置、顶点等信息
表情管理器:记录全部Text中图片(有效的)位置、纹理、顶点信息的索引关系,由数据变化时生成须要的Mesh信息并提交
SpriteAsset 管理器:管理图片中全部Text中使用的图片资源加载以及sprite位置、名字信息。
最初的源码看似可用,可是在手机端ListView滚动状况下直接掉到20帧一下,即便在静态100个表情同时更新的境况下效率也很难使人满意。因此.................差很少用了一周时间爬各类坑,下面是一些主要的记录:
代码中在解析字符中基本每次都在new数据,包括解析字符、计算图片位置、更新图片Mesh等都存在很严重的GC,看上图就能够看到滚动中若是频繁建立的问题。
优化思路:
启动时读取配置信息,并简历sprite名字和信息的对应Dictionary,加快查找。固然也能够直接以Dictionary结构进行序列化,就能够节省这部分空间和时间,待优化。
原始版本中有效Sprite 列表时经过List的形式进行管理,每次任一个Text的变化(enabled,posotion等)都会将这个列表清除并从新将有效Text中的有效Sprite添加到列表中来。这种方式若是在相似ListView等一直会变化的组件中就会产生没必要要的CPU开销。
优化思路:
这种方式避免在频繁更新中没必要要的列表清除操做以及对SpriteManager lateUpdate的影响
最初的版本采用对SpriteList遍历的形式逐个将triangles、uv、vertices 赋值到新建立的缓存中,再扔给iMesh去提交。在ListView快速移动时这部分的时间占用就很夸张了。
优化思路:
原始版本可能时做者计算错误了,清除乱码的UV位置其实只须要向后4个便可,可是也原始版本是按4 * Length(标签长度)来计算,这项的CPU占用率特别高。
原始版本时在SpriteUpdate中每隔固定时间更新表情的索引(若是有)并从新更新Sprite Mesh内容。会产生一个问题:每种类型表情动画图片的数目不同,那就很难保证每一个动态表情都很天然的播放。提升更新的间隔意味着有些表情像发飙同样
优化思路:
每类型的表情中单独存放其时间间隔以及已经运行的时间,在Update中根据各自的状况进行更新。
原始代码中是在Text :SetVerticesDirty()中进行ParseText的操做并依赖SpriteManager中LaterUpdate更新图片的Mesh数据,产生的问题:
优化思路:
对应的还有编辑器、数据结构、贴图资源管理等的优化
支持 "[xxxxx]"来替代
方便单个Canvas下多个层级,让Text 能够直接设置SpriteManager或者找最近的一个。
(1)下划线解析和超连接解析都是基于字符位置对应实际字符顶点位置
(2)字符串解析
(3)图片Mesh
(4)多张sprite Asset
测试方式,屏幕中160个动画表情的状况,在ListView中快速滚动下进行测试的性能曲线(主要时CPU);
优化前
优化后
原生Text, 有占位符,无表情
采用这种方案各类缘由都有,有好处也有弊端,就像层级问题,解决起来会有点头痛。通过一段时间优化勉强能够在移动端知足需求,不过还有不少能够继续优化的空间。
GITHUB工程文件:https://github.com/carlosCn/Unity-EmojiText
百度网盘资源:http://pan.baidu.com/s/1geZuVNd
欢迎继续补充。