该组件是基于Unity2019.4.1f1版本的图文混排组件,实现了静态表情,动态表情,超链接,多图集加载等功能。该组件属于学习用途,不完善的地方可以提取源码自行修改。其中关于超链接点击响应部分关于lua的消息广播如果报错可以自行注释或者删除。该组件核心脚本EmojiText.cs,原理和以往的图文混排组件一样重写Text的OnPopulateMesh(VertexHelper toFill)函数,但是因为unity2019中的某个版本往上的版本unity优化了text,在某些情况下不在存储完整的顶点信息,例如富文本,空格等信息的顶点信息会缺失,该组件规避了这个缺点,文本正则匹配标签的时候替换掉被unity优化的内容去计算顶点和占位符信息,重写OnPopulateMesh函数的时候,同时也去除有可能会被unity优化的顶点信息,这样就可以保证顶点信息的统一,规避了因为unity的优化规则引起的顶点的缺失导致的文本顶点信息计算出现的偏差错漏。
富文本等替换代码:
private string ReplaceRichText(string str)
{
str = Regex.Replace(str, @"<color=(.+?)>", "");
str = str.Replace("</color>", "");
str = Regex.Replace(str, @"<size=(\d)>", "");
str = str.Replace("</size>", "");
str = str.Replace("<b>", "");
str = str.Replace("</b>", "");
str = str.Replace("<i>", "");
str = str.Replace("</i>", "");
str = str.Replace("\n", "");
str = str.Replace("\t", "");
str = str.Replace("\r", "");
str = str.Replace(" ", "");
return str;
}
OnPopulateMesh函数重写
protected override void OnPopulateMesh(VertexHelper toFill)
{
if (font == null)
{
return;
}
m_DisableFontTextureRebuiltCallback = true;
var orignText = m_Text;
m_Text = parseText;
Vector2 extents = rectTransform.rect.size;
var settings = GetGenerationSettings(extents);
cachedTextGenerator.Populate(text,settings);
m_Text = orignText;
IList<UIVertex> verts = cachedTextGenerator.verts;
float unitsPerPixel = 1 / pixelsPerUnit;
Rect inputRect = rectTransform.rect;
Vector2 textAnchorPivot = GetTextAnchorPivot(alignment);
Vector2 refPoint = Vector2.zero;
refPoint.x = Mathf.Lerp(inputRect.xMin, inputRect.xMax, textAnchorPivot.x);
refPoint.y = Mathf.Lerp(inputRect.yMin, inputRect.yMax, textAnchorPivot.y);
Vector2 roundingOffset = PixelAdjustPoint(refPoint) - refPoint;
int vertCount = verts.Count;
#region 剔除无用顶点
List<UIVertex> pureVerts = new List<UIVertex>();
for (int i = 0; i < vertCount; ++i)
{
if (i % 4 == 3)
{
if (verts[i].position != verts[i - 1].position &&
verts[i - 2].position != verts[i - 3].position &&
verts[i].position != verts[i - 2].position &&
verts[i].position != verts[i - 3].position)
{
pureVerts.Add(verts[i - 3]);
pureVerts.Add(verts[i - 2]);
pureVerts.Add(verts[i - 1]);
pureVerts.Add(verts[i]);
}
}
}
vertCount = pureVerts.Count;
#endregion
toFill.Clear();
for (int i = 0; i < vertCount; ++i)
{
int tempVertsIndex = i & 3;
m_TempVerts[tempVertsIndex] = pureVerts[i];
m_TempVerts[tempVertsIndex].position *= unitsPerPixel;
if (roundingOffset != Vector2.zero)
{
m_TempVerts[tempVertsIndex].position.x += roundingOffset.x;
m_TempVerts[tempVertsIndex].position.y += roundingOffset.y;
}
if (tempVertsIndex == 3)
{
EmojiInfo emoji = null;
for (int j = 0; j < m_EmojiInfos.Count; j++)
{
if (m_EmojiInfos[j].Index == (i - 3))
{
emoji = m_EmojiInfos[j];
break;
}
}
if (emoji != null)
{
for (int j = 0; j < 4; j++)
{
m_TempVerts[j].uv0 = Vector2.zero;
emoji.Pos[j] = m_TempVerts[j].position;
}
}
toFill.AddUIVertexQuad(m_TempVerts);
}
}
m_DisableFontTextureRebuiltCallback = false;
DealHrefLink(toFill);
dirtyTag = true;
}
需要详细代码的自取 链接:https://pan.baidu.com/s/1_0lMjSPlnBxggBOL2swRPQ 提取码:p27x
|