感觉使用Unity之后总能看到各种各样解决混排的方案,只能说明Unity不够体恤下情啊。这篇文章主要讲一下个人在使用过程中方案选择和优化过程,已做记录。顺便提下,开源很多意味着坑,还是要开实际需求。
1 TextMeshPro
Unity 最近公布收购了TextMeshPro并且免费开源给大家使用,估计还需要几个小版本才会完全融合到Unity中或者保持现在的状态。TextMeshPro支持效果丰富,兼容现在UI层级等,性能也可以满足移动端,但是很纠结的是:
基于上面亮点,最后我还是没有采用这种方案,如果Unity考虑融合进来,建议修改下字库的使用方式。
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个表情同时更新的境况下效率也很难令人满意。所以.................差不多用了一周时间爬各种坑,下面是一些主要的记录:
优化思路:
启动时读取配置信息,并简历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);
优化前
采用这种方案各种原因都有,有好处也有弊端,就像层级问题,解决起来会有点头痛。经过一段时间优化勉强可以在移动端满足需求,不过还有很多可以继续优化的空间。
GITHUB工程文件:https://github.com/carlosCn/Unity-EmojiText
百度网盘资源:http://pan.baidu.com/s/1geZuVNd
欢迎继续补充。
联系客服