Skip to content

Instantly share code, notes, and snippets.

@Autumn1992
Last active July 11, 2018 09:10
Show Gist options
  • Save Autumn1992/22f7f13c89fbf07d5bc5483b8f38ab47 to your computer and use it in GitHub Desktop.
Save Autumn1992/22f7f13c89fbf07d5bc5483b8f38ab47 to your computer and use it in GitHub Desktop.
Unity UGUI UITextUnderLinen Effect
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
[ExecuteInEditMode]
[RequireComponent(typeof(Text))]
public class UnderLine : BaseMeshEffect
{
private static readonly List<UIVertex> verts = new List<UIVertex>();
private static readonly UIVertex[] data = new UIVertex[4];
public Text text;
public Color UnderlineColor = Color.black;
public float LineOffset = 1;
public float LineThickness = 2;
protected UnderLine() { }
protected override void Awake()
{
base.Awake();
text = GetComponent<Text>();
if (text.font == null)
{
Destroy(this);
Debug.LogWarning("Text.font is null");
return;
}
text.RegisterDirtyMaterialCallback(OnFontMaterialChanged);
text.font.RequestCharactersInTexture("*", text.fontSize, text.fontStyle);
}
protected override void OnDestroy()
{
text.UnregisterDirtyMaterialCallback(OnFontMaterialChanged);
base.OnDestroy();
}
private void OnFontMaterialChanged()
{
text.font.RequestCharactersInTexture("*", text.fontSize, text.fontStyle);
}
private Vector2 GetUnderlineCharUV()
{
//return Vector2.zero;
var ch = '*';
CharacterInfo info;
//此处只是为了确保 动态Font的贴图准备好了 并没有其它意义
if (text.font.GetCharacterInfo(ch, out info, text.fontSize, text.fontStyle))
{
return (info.uvBottomLeft + info.uvBottomRight + info.uvTopLeft + info.uvTopRight) * 0.25f;
}
Debug.LogWarning("GetCharacterInfo failed");
return Vector2.zero;
}
public override void ModifyMesh(VertexHelper vh)
{
if (!IsActive())
return;
if (vh.currentVertCount < 3)
return;
verts.Clear();
vh.GetUIVertexStream(verts);
var neededCpacity = verts.Count + 6;
if (verts.Capacity < neededCpacity)
verts.Capacity = neededCpacity;
UIVertex vert = UIVertex.simpleVert;
vh.PopulateUIVertex(ref vert, 3);
var pos_a = vert.position;
//此处计算最后一个顶点 verts.Count * 2 / 3 - 2公式是由mesh的共享顶点规则得到的 此处取到顶点的y轴 如果取的字符小 y的值
//会很小 所以此处实际应该直接用fontsize来计算 再结合此处顶点的x轴坐标
vh.PopulateUIVertex(ref vert, verts.Count * 2 / 3 - 2);
var pos_b = vert.position;
//此处的计算也可能会有偏差 当Text的Alignment不是Center时 注意额外的偏移计算
var y = -text.fontSize / 2;
var pos0 = new Vector3(pos_a.x, y - LineOffset);
var pos1 = new Vector3(pos_b.x, y - LineOffset);
var pos2 = new Vector3(pos_b.x, y - LineOffset - LineThickness);
var pos3 = new Vector3(pos_a.x, y - LineOffset - LineThickness);
vert.color = UnderlineColor;
vert.uv0 = GetUnderlineCharUV();
vert.position = pos0;
data[0] = vert;
vert.position = pos1;
data[1] = vert;
vert.position = pos2;
data[2] = vert;
vert.position = pos3;
data[3] = vert;
vh.AddUIVertexQuad(data);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment