最终效果如上图所示。
问题背景
UI.Text 默认的排列方式是横向的:
如果要让这些字符竖向排列,查阅了半天 API 和成员变量相关文档,都没有找到对应的参数。最终在 UI.Effect 的实现中发现了线索:
// 摘要:
// Adds an outline to a graphic using IVertexModifier.
[AddComponentMenu("UI/Effects/Shadow", 14)]
public class Shadow : BaseMeshEffect
可以借鉴 Shadow 的相同手法,对 Text 进行顶点修改。
实现思路
处理后的代码效果是让"123456"竖向排列。这里只提供基本方法思路:由于重新定义了 UIVertex 的相关信息,字符的排列规则(如对齐方式)也需要重写,本文不深入展开,仅作抛砖引玉。
完整代码
[AddComponentMenu("Extension/VerticalText")]
[RequireComponent(typeof(UnityEngine.UI.Text))]
public class VerticalText : BaseMeshEffect
{
Vector2 SetOneCharPosition(ref VertexHelper vh, int idx, Vector3 pos0)
{
if (idx % 4 != 0 || vh == null) return Vector2.zero;
var tex0 = new UIVertex();
vh.PopulateUIVertex(ref tex0, idx);
var tex1 = new UIVertex();
vh.PopulateUIVertex(ref tex1, idx + 1);
var tex2 = new UIVertex();
vh.PopulateUIVertex(ref tex2, idx + 2);
var tex3 = new UIVertex();
vh.PopulateUIVertex(ref tex3, idx + 3);
float width = tex0.position.x - tex1.position.x;
float height = tex0.position.y - tex3.position.y;
var offset = pos0 - tex0.position;
tex0.position = pos0;
tex1.position += offset;
tex2.position += offset;
tex3.position += offset;
vh.SetUIVertex(tex0, idx);
vh.SetUIVertex(tex1, idx + 1);
vh.SetUIVertex(tex2, idx + 2);
vh.SetUIVertex(tex3, idx + 3);
// Debug.LogError(offset + " " + tex0.uv0 + " " + tex0.uv1);
return new Vector2(width, height);
}
public override void ModifyMesh(VertexHelper vh)
{
// var num = vh.currentVertCount;
var text = this.GetComponent<Text>();
var strs = text.text.Split('|');
int ColStartIndex = 0;
int vertexStartIndex = 0;
/* for (int colIndex = 0; colIndex < strs.Length; colIndex++, vertexStartIndex += 4)
{
{
UIVertex VertexOne = new UIVertex();
vh.PopulateUIVertex(ref VertexOne, 0);
SetOneCharPosition(vh, 0, VertexOne.position);
}
}
*/
UIVertex VertexOne0 = new UIVertex();
vh.PopulateUIVertex(ref VertexOne0, 0);
float HEIGHT_PER_UNIT = 30f;
float height_current = 0f;
for (int col = 0; col < vh.currentVertCount; col++)
{
UIVertex VertexOne = new UIVertex();
vh.PopulateUIVertex(ref VertexOne, col);
height_current = 0f;
float dx = 0f;
dx = col * 30f;
for (int i = 0; i < vh.currentVertCount; i += 4)
{
float h = this.SetOneCharPosition(ref vh, i, VertexOne0.position + new Vector3(dx, 0f - HEIGHT_PER_UNIT * ((i) / 4), 0f)).y;
height_current += 30f;
if (height_current + 30f >= this.GetComponent<RectTransform>().rect.height)
return;
// Debug.LogError(this.GetComponent<RectTransform>().rect.height + " cur=" + height_current);
}
}
}
}