Unity游戏开发之图文混排的策略
作者: scottcgi
来源: https://blog.csdn.net/tom_221x/article/details/113456808?utm_source=app&app_version=4.6.1
首先,我们看一下官方说明。
This is only useful for text meshes and renders an image inline with the text.
关键词在于:text meshes 和 image inline ——这说明,<quad/>设计是用在TextMesh而不是Text,并且它是一个文本内嵌图片,即可以自动图文混排。
其次,看一下官方例子。
<quad material=1 size=20 x=0.1 y=0.1 width=0.5 height=0.5>
This selects the material at position in the renderer’s material array and sets the height of the image to 20 pixels.
material——是
TextMesh对应MeshRender中Materials数组的索引。size——是图片的
像素高度。
The rectangular area of image starts at given by the x, y, width and height values, which are all given as a fraction of the unscaled width and height of the texture.
x,y——是图片在texture上的 百分比偏移,如果texture是一个纹理集合,上面有很多表情,就可以用xy偏移到其中任意一个表情。width——是图片显示宽度的 百分比缩放,即:显示宽度 = size * width。也就是说,width越大,图片显示宽度越大,反之越小。
<quad material=1 size=0300 width=2 height=1 />
<quad material=1 size=0300 width=1 height=1 />
<quad material=1 size=0300 width=0.5 height=1 />
123

height——是图片显示高度的 缩放百分比,即:图片显示高度 = 实际高度 / height。也就是说,height越大,图片显示高度越小,反之越大。
<quad material=1 size=0300 width=1 height=2/>
<quad material=1 size=0300 width=1 height=1/>
<quad material=1 size=0300 width=1 height=0.5/>
123
因此,我们可以看出:像素宽度 = size * (width / height)。也就是说,只要width和height保持1:1,像素宽度就不变,同时width越大显示宽度越大,height越大显示高度越小,反之width越小显示宽度越小,height越小显示高度越大。
微信搜索公众号 [爱上游戏开发],回复 “资料”,免费领取 200G 学习资料!
<quad material=1 size=0300 width=2 height=2/>
<quad material=1 size=0300 width=1 height=1 />
<quad material=1 size=0300 width=0.5 height=0.5 />
123

接着,在Text中使用的情况。
第一,显然就是无法与 MeshRender配合,正确检索到material的索引。第二,不仅无法正确使用material,还会显示前文所示的乱码。
但好的一面就是:<quad/>的属性可以正确设置图片大小,而<quad/>的大小会自动排版,那么我们就可以用<quad/>来做占位,进行图文混排的实现。
然后,使用在Text中图文混排,需要解决的问题。
第一,消除乱码。 第二,用正确的图片替换占位符。 第三,控制占位符大小。
第一个问题,可以使用重写Text的protected override void OnPopulateMesh(VertexHelper toFill)方法来解决,即找到
第二个问题,可以利用position直接,将正确的图片替换到正确的未知。
如何确定toFill中索引?
这里有一个技巧,就是如果material!=0,那么所有toFill的尾部——这样我们就可以,把Text中的toFill的尾部替换即可。
核心的实现代码如下:
protected override void OnPopulateMesh(VertexHelper toFill)
{
base.OnPopulateMesh(toFill);
var count = this.spriteInfoList.Count;
if (count > 0)
{
var vertexLastIndex = toFill.currentVertCount - 1;
var spriteLastIndex = count - 1;
var leftBottom = new UIVertex();
for (var i = spriteLastIndex; i > -1; --i)
{
var index = vertexLastIndex - (spriteLastIndex - i) * 4;
toFill.PopulateUIVertex(ref leftBottom, index);
toFill.SetUIVertex ( leftBottom, index - 1);
toFill.SetUIVertex ( leftBottom, index - 2);
toFill.SetUIVertex ( leftBottom, index - 3);
var imageRT = this.transform.GetChild(i).GetComponent<Image>().rectTransform;
var pos = (Vector2) leftBottom.position + imageRT.sizeDelta / 2;
imageRT.SetLocalPositionXY(pos);
}
}
}
12345678910111213141516171819202122232425262728293031
第三个问题, 由前文可知,我们可以使用像素 height = size,像素width = size * (width / height)。
那么,令height = 1,则:size = 像素height,width = 像素width / size。
例如:一个图片的大小是——width = 300px,height = 500px——对应的就是:
最后,使用实现Text图文混排的限制。
这些限制,其实是Text实现的bug。
第一,如果 Text VerticalWrapMode是Truncate且text内容已经truncated,那么将显示乱码,并且 toFill vertexes将会出现大量重复冗余顶点。第二,如果 的size超过 500,那么的height和position将会在 cachedTextGeneratorForLayout.GetPreferredHeight的计算中出现错误的数值。
-- END --

公众号后台回复「资料」获取超多学习福利
>>> 点击进入技术讨论群 <<< ▽想深入了解么?
长按/扫码关注我吧↑↑↑
觉得不错就点个在看吧!

