前言:大家在Unity里做文字的自动换行与图片文字适配是怎么做的?
今天在游戏项目中有个需求,想让任务的每个子任务框都随着任务描述的文字来动态修改。对于这种需求,我有两个解决方案:
1、使用Unity的布局组件 Vertical Layout Group 与 ContentSizeFitter 一起控制,这种方式轻松省力,但对于某些特殊需求不好拓展。
2、自己根据内容算大小,根据每一行多少字得到总共多少行。然后设置文本框的 sizeDelta 和对应的背景框的 sizeDelta 。这种可拓展性好很多,但是需要自己解析以及控制长宽,比较麻烦。
我今天碰到的这个我就是用第一种办法来做的,但是第一种方法不适合在满足适配的情况下做一些其他操作,因为我们通常做操作是在赋值之后立马去做的,而我们给 Text 的 text 赋值时,并不会立马得到真实的 text 大小(猜测 text 的值是这一帧就赋好了,但是 preferredWidth 没有立即计算改变,可能是在下一帧才计算的,而此时布局组件也就没有针对真正的大小来布局,所以当前这一帧的大小有可能是不对的)。而在这里赋值后我还需要得到这个 Element 的大小,所以拿到的也不对。
我开始冒出的想法就是使用协程,在下一帧拿到正确的 Element 大小时再做操作,一帧玩家应该看不太出。但协程也有几个问题:
1、协程每次运行都开了一个线程,很费。
2、你没办法完美控制好在一帧后的执行,时间设置久了太明显,短了受限于机器可能拿到的数据还是错误数据,不是很稳妥。(那个 Text 大小也不一定是一帧后就正确了)。
3、代码很难理解日后不好维护。
在我和同事的思考下,决定从那个控制大小的布局组件入手。我们发现 ContentSizeFitter 当改变大小的时候有一个回调函数,有了这个,我们可以写一个类去继承这个 ContentSizeFitter 类,并重写父类的方法,同时在子类中添加一个委托,当我们在改变 Element 大小的时候还需要 Element 正确的大小去做其他事情时,可以自己给这个委托赋值让其执行。这样这个布局组件的拓展性就好很多了,玩家可以自由订制。实际验证了一下,还是比较好用。
ContentSizeFitter 改变大小的回调函数
复写的子类CustomContentSizeFitter
游戏的实际效果 右边为改变文字后的效果(额外的操作也顺利完成)
Element 的设置界面
Element 子物体文字设置
题外话
以前我做聊天的适配时,需要根据每个发言玩家的称号适配称号背景,并根据发的文字适配聊天框带大小。当时我是用的第2种方法,自己去实时计算大小再手动改变图片和文本框的 sizeDelta ,但是那个大小同样是有问题的,而为了赶进度图方便直接用了协程,所以玩家在发言后的短暂空隙内,可以看到自己的称号背景图被动态改变,体验不是很好但也勉强满足策划的需求。办法总是人想出来的,现在想想,还是不能图方便放过自己啊,放过自己就错过了一次学习的机会!