天天看点

unity 图文混排方案

在我们工作中,可能经常有这样的需求,就是需要图文混排,因为这个对于原生或web都是比较容易的事情。但是我们用unity的话,首先unity最开始只想做纯游戏侧的引擎,一开始甚至还没有一个商业化的ui工具,后面才结合了ngui成为ugui,当然现在也出现了uielement。但要做到图文混排一开始还是不容易的,需要四处找插件,甚至需要自己想办法文字和图片自己做结合来实现。

经过了一段时间后unity出现了textmesh,他可以实现图文混排,他图文混排的方式相当于是多一个材质,然后再语法上用类似<quad material=1>来实现。实际上他也能实现图文混排的方式,只需要打个图集,把图集放到材质上,材质放到textmesh的第二个材质上就好了。

unity 图文混排方案

这个图集材质是长这样的:

unity 图文混排方案

实现的效果是:

unity 图文混排方案

看上去没问题,能实现效果。但是他有几个问题:

第一就是他的设置图片的方式:<quad material=1 x=0.001953125 y=0.244140625 width=0.25 height=0.125/>

注意这里的x,y,width,height都是0到1的,也就是你需要自己把图片的位置和图片的宽高通过图集的宽高换算出来(实际上就是算偏移)。

比如x=250;图集的宽是1024;那么真正的x就是250/1024。

这里如果你的表情多,就会有很多这种除法运算,整体来说效率不高。

第二就是你用在输入框或者表情列表下的话你可能就很难做了。

因为输入框我们如果用ugui的话,他已经帮我们关联好相关输入的信息,我们貌似没办法给他增加TextMesh方式来实现图文混排的效果(如果这个不重要用标记代替也行)

unity 图文混排方案

但是致命的是你可能没办法再一个drawcall下用TextMesh来实现表情列表。因为ugui里面的材质都不支持多材质。

unity 图文混排方案

当然如果你说不用ugui或者自己改造,用mesh自己实现也是可以的。但是你就要做很多适配的工作了。

也就衍生出以下说的一种比较适合上面我说的情况的,需要图文混排,需要文字输入中带图片,需要列表只有一个drawcall。

那就是TextMeshPro了。

这个是后面unity引进来的TextMesh的升级版。unity甚至把他接入到了各种text里面。

unity 图文混排方案

用Tmp实现图文混排就简单了。

我们用的是spriteasset的方式。

使用<sprite="DefaultSprites" name="Unity">的方式显示一个表情, sprite是textmeshpro集的命,name是具体的图片,也可以用index。

另外textmeshpro集要放在“TextMesh Pro\Resources\Sprite Assets”下(除非你改了他的路径),改路径的地方是

unity 图文混排方案

如果我们要支持中文或其他语言,我们就修改下fontasset的字体就好:

点击:

unity 图文混排方案

选择这个fontasset,然后修改下面这里:

unity 图文混排方案

一般不需要自己做字体,除非你有特殊字体。

但是我们现在只有默认的表情

unity 图文混排方案

我们当然像要自己的表情,那就需要自己来制作一下表情图集了。

我用的是TexturePacker来把图集打出来。但是要注意不要让他支持旋转,让他正常排列就好。

unity 图文混排方案

然后在图集上选择sprite和spritemode选择multiple,这样才能编辑图片

unity 图文混排方案

选择sprite editor

unity 图文混排方案

这里注意锚点一定要放在左下角,然后保存。

然后需要制作具体的fontasset了,右键这个图集:

unity 图文混排方案

制作好的图集放在我们设置的spriteasset的目录下:

unity 图文混排方案

放到这里就可以在项目中用这些表情。

最终展示效果

unity 图文混排方案

这个文本时这样出来的:

unity 图文混排方案

然后其他的展示效果如下:

unity 图文混排方案

这里说以下表情列表需要更改下他们的render queue,让相同的材质在一个queue下,不同的不要在一个queue下,这样才能让他们合批。以下时其中一个示例

unity 图文混排方案

好了,对比下一排和两排的效果,可以看到他们没有drawcall的增加,我们的需求解决了。

unity 图文混排方案

下面是两排的示例:

unity 图文混排方案

但是这里要注意的是不支持gif,gif图片可以用序列帧的方式来播放。建议发gif动画就单发,不要连着文字一起发,也就是点击gif的表情就发出去把,不让他带文字了。

继续阅读