/// <summary> /// 解析精灵和精灵动画占位符信息 /// </summary> /// <param name="str">字符串</param> public void ParsingSprite(string str) { //解析标签属性 m_QuadPlaceHolderInfos.Clear(); foreach (Match match in RichTextConst.SpriteRegex.Matches(str)) { QuadPlaceholder teamQuadInfo = new QuadPlaceholder(); teamQuadInfo.isAnimate = false; teamQuadInfo.sprite = match.Groups[1].Value; teamQuadInfo.length = match.Length; teamQuadInfo.index = match.Index * 4; teamQuadInfo.size = new Vector2(fontSize, fontSize); m_QuadPlaceHolderInfos.Add(teamQuadInfo.index, teamQuadInfo); } foreach (Match match in RichTextConst.AnimateRegex.Matches(str)) { QuadPlaceholder teamQuadInfo = new QuadPlaceholder(); teamQuadInfo.isAnimate = true; teamQuadInfo.sprite = "1"; teamQuadInfo.rate = int.Parse(match.Groups[2].Value); teamQuadInfo.animateName = match.Groups[1].Value; teamQuadInfo.length = match.Length; teamQuadInfo.index = match.Index * 4; teamQuadInfo.size = new Vector2(fontSize, fontSize); m_QuadPlaceHolderInfos.Add(teamQuadInfo.index, teamQuadInfo); } }
/// <summary> /// 生成uv信息 /// </summary> /// <param name="info"></param> /// <param name="startVertex"></param> /// <param name="unitsPerPixel"></param> /// <returns></returns> public int GenerateVertices(QuadPlaceholder info, Vector3 postion, int startVertex, float unitsPerPixel) { TextMeshInfo tempUv = new TextMeshInfo(); tempUv.startPos = postion * unitsPerPixel; //设置图片的位置 tempUv.vertices = new Vector3[4]; tempUv.vertices[0] = new Vector3(0, 0, 0) + tempUv.startPos; tempUv.vertices[1] = new Vector3(info.size.x, info.size.y, 0) + tempUv.startPos; tempUv.vertices[2] = new Vector3(info.size.x, 0, 0) + tempUv.startPos; tempUv.vertices[3] = new Vector3(0, info.size.y, 0) + tempUv.startPos; TexturePackSprite sprite = null; if (info.isAnimate) { RichTextAnimate textAnimate = textSpriteAsset.GetAnimateListByName(info.animateName); if (textAnimate != null) { sprite = textAnimate.spriteList[0]; } } else if (textSpriteAsset.spriteInfoList != null) { int index = int.Parse(info.sprite); if (textSpriteAsset.spriteInfoList.Count > index) { sprite = textSpriteAsset.spriteInfoList[index]; } } Vector2 texSize = Vector2.zero; if (sprite == null) { startVertex += 4 * info.length - 1; return(startVertex); } //计算其uv texSize = new Vector2(textSpriteAsset.spriteSheet.width, textSpriteAsset.spriteSheet.height); tempUv.uv = new Vector2[4]; if (!sprite.rotated) { tempUv.uv[0] = new Vector2(sprite.x / texSize.x, sprite.y / texSize.y); tempUv.uv[1] = new Vector2((sprite.x + sprite.width) / texSize.x, (sprite.y + sprite.width) / texSize.y); tempUv.uv[2] = new Vector2((sprite.x + sprite.width) / texSize.x, sprite.y / texSize.y); tempUv.uv[3] = new Vector2(sprite.x / texSize.x, (sprite.y + sprite.width) / texSize.y); } else { tempUv.uv[0] = new Vector2(sprite.x / texSize.x, sprite.y / texSize.y); tempUv.uv[1] = new Vector2((sprite.x + sprite.width) / texSize.x, (sprite.y + sprite.width) / texSize.y); tempUv.uv[2] = new Vector2((sprite.x + sprite.width) / texSize.x, sprite.y / texSize.y); tempUv.uv[3] = new Vector2(sprite.x / texSize.x, (sprite.y + sprite.width) / texSize.y); } //声明三角顶点所需要的数组 tempUv.triangles = new int[6]; startVertex += 4 * info.length - 1; RendererInfo rendererInfo = new RendererInfo(); rendererInfo.uvInfo = tempUv; rendererInfo.placeholder = info; m_RendererInfo.Add(rendererInfo); return(startVertex); }
/// <summary> /// 重写绘制 /// </summary> /// <param name="toFill">模型</param> protected override void OnPopulateMesh(VertexHelper toFill) { if (font == null) { return; } // We don't care if we the font Texture changes while we are doing our Update. // The end result of cachedTextGenerator will be valid for this instance. // Otherwise we can get issues like Case 619238. m_DisableFontTextureRebuiltCallback = true; Vector2 extents = rectTransform.rect.size; var settings = GetGenerationSettings(extents); bool error = cachedTextGenerator.PopulateWithErrors(m_Content, settings, gameObject); // Apply the offset to the vertices IList <UIVertex> verts = cachedTextGenerator.verts; float unitsPerPixel = 1 / pixelsPerUnit; //Last 4 verts are always a new line... (\n) int vertCount = verts.Count - 4; Vector2 roundingOffset = new Vector2(verts[0].position.x, verts[0].position.y) * unitsPerPixel; roundingOffset = PixelAdjustPoint(roundingOffset) - roundingOffset; toFill.Clear(); //偏移情况,目前不考虑 if (roundingOffset != Vector2.zero) { for (int i = 0; i < vertCount; ++i) { int tempVertsIndex = i & 3; m_TempVerts[tempVertsIndex] = verts[i]; m_TempVerts[tempVertsIndex].position *= unitsPerPixel; m_TempVerts[tempVertsIndex].position.x += roundingOffset.x; m_TempVerts[tempVertsIndex].position.y += roundingOffset.y; if (tempVertsIndex == 3) { toFill.AddUIVertexQuad(m_TempVerts); } } } else { //绘制表情替换占位符的顶点 m_TextureUvInfos.Clear(); if (m_RichTextSpriteRender != null) { m_RichTextSpriteRender.Clear(); } for (int idx = 0; idx < vertCount; idx++) { QuadPlaceholder info = null; if (m_RichTextSpriteRender != null && supportRichText && m_QuadPlaceHolderInfos.TryGetValue(idx, out info)) { //占位符的其实定点在左上角,+3 第四个顶点在左下角 if (verts.Count <= info.index + 3) { continue; } idx = m_RichTextSpriteRender.GenerateVertices(info, verts[info.index + 3].position, idx, unitsPerPixel); } else { //继续绘制字体 int tempVertsIndex = idx & 3; m_TempVerts[tempVertsIndex] = verts[idx]; m_TempVerts[tempVertsIndex].position *= unitsPerPixel; if (tempVertsIndex == 3) { toFill.AddUIVertexQuad(m_TempVerts); } } } } m_DisableFontTextureRebuiltCallback = false; if (!supportRichText) { return; } //绘制下划线 if (m_UnderLineInfos != null && m_UnderLineInfos.Count > 0) { OnDrawUnderLine(toFill, settings, verts); } if (m_LinkInfos != null && m_LinkInfos.Count > 0) { OnDealLinkerBoundsBox(toFill, verts); } //网格重绘 if (m_TextureUvInfos != null && m_RichTextSpriteRender != null) { m_RichTextSpriteRender.Draw(); } }