最终效果如上图所示。

问题背景

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);
            }
        }
    }

}