Last active
July 11, 2018 09:10
-
-
Save Autumn1992/22f7f13c89fbf07d5bc5483b8f38ab47 to your computer and use it in GitHub Desktop.
Unity UGUI UITextUnderLinen Effect
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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