zl程序教程

您现在的位置是:首页 >  系统

当前栏目

UGUI表情系统解决方案

系统解决方案 表情 Ugui
2023-09-11 14:14:32 时间

聊天是游戏中必不可少的功能,发送表情也是聊天系统的一个重要组成部分。笔者的项目中使用UGUI开发UI,在制作表情系统时也遇到了同样的问题,可是UGUI中的Text组件本身并不支持图文混编。为此,笔者提供了一套解决方案,供大家参考。

这是侑虎科技第147篇原创文章,感谢作者邹春毅(QQ:442319386,作者博客:https://github.com/zouchunyi)供稿。如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨。(QQ群465082844)同时,作者也是U Sparkle活动参与者哦,UWA欢迎更多开发朋友加入 U Sparkle开发者计划,这个舞台有你更精彩!


Unity推荐的方式是使用TextMesh解决混编问题。TextMesh的确可以实现混编,但是却存在和UGUI较难整合的问题(Mask遮罩、自适应等),同时也会因为使用多个材质导致无法使用动态批次合并。网上也有人使用Text+Image的形式来处理图文混编,但是需要解决排序等问题。最好的解决方案还是能让UGUI的Text能够自身支持图文混编。

通过查看UGUI的源代码和其Shader,可以重写Text生成Mesh的方法以及最终渲染的Shader,以此来实现图文混编的功能,后文会为大家一步步介绍实现方法。



整合表情图片

请输入图片描述

这是原始的表情资源,按照表情名_序列帧的形式统一命名,然后通过代码打成一张Atlas,为了能够支持动态表情,需要在Shader中使用UV动画,但是因为所有的表情都在一张Atlas中,帧数又不统一,因此需要再生成一张可以标识每一个表情有多少帧的数据贴图。
请输入图片描述
表情和数据Atlas,这两张图片会在最终渲染的Shader中使用。

请输入图片描述
当然还需要生成一张数据表,用户标识表情名和Text替代符的对应关系,以及每一个表情的UV位置。其中Key中的内容就是在Text中的表情替代符,至于为什么使用这种格式会在后面内容介绍。



重写Text中生成顶点的方法

这是比较关键的步骤,UGUI中Text生成顶点的规律是每个字符生成4个顶点,构成2个面。例如字符串:这是一个Text,在UGUI中会生成8x4=32个顶点,中文、英文、其他字符都是等价的,只是顶点之间的间距不同。因此可以在将表情替代符中的多个顶点修改成适合表情的4个顶点,使用第二套UV标识这部分顶点引用表情贴图,而非字体贴图。例如一个字符串:这里是表情[

请输入图片描述
读取配置文件,用于后面替换表情符。

请输入图片描述
利用正则表达式找出全部的表情符,并且匹配是否为系统所支持的表情符(上面读取的配置文件)。

请输入图片描述
重新生成顶点位置和UV坐标。



重写渲染部分

这是最后一步,重写一个Shader用来渲染。相较于原始Shader增添了几个新的属性。
请输入图片描述
其中_EmojiSize表示EmojiTexture每一行拥有几个表情,因为本示例中每一行有4个表情,所以这个位置填写4。其他的属性就不做阐述了。

请输入图片描述
引入第二套uv坐标。

请输入图片描述
VS几乎没多大变化,只是传递第二套UV坐标。

请输入图片描述
PS中先判断第二套UV坐标是否有数值,有数值则表明是表情,从_EmojiTex中绘制,从_EmojiDataTex中读取表情帧数,用于做uv动画。

请输入图片描述
至此,就实现了UGUI的表情系统,可以和原生的其他UGUI控件使用。同时因为只有一个材质,一个Pass,所以也可以进行动态批次合并。

工程代码笔者以上传到自己的Github中,https://github.com/zouchunyi/EmojiText,欢迎大家Clone。

文末,再次感谢邹春毅的分享,如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨。(QQ群465082844)。
也欢迎大家来积极参与U Sparkle开发者计划,简称"US",代表你和我,代表UWA和开发者在一起!