基于Unity2019版本的UGUI图文混排组件

该组件是基于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, @"", "");
            str = str.Replace("", "");
            str = Regex.Replace(str, @"", "");
            str = str.Replace("", "");
            str = str.Replace("", "");
            str = str.Replace("", "");
            str = str.Replace("", "");
            str = str.Replace("", "");
            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;
            }           
            
            // 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;

            var orignText = m_Text;
            m_Text = parseText;

            Vector2 extents = rectTransform.rect.size;

            var settings = GetGenerationSettings(extents);
            cachedTextGenerator.Populate(text,settings);
            m_Text = orignText;

            // Apply the offset to the vertices
            IList<UIVertex> verts = cachedTextGenerator.verts;
            float unitsPerPixel = 1 / pixelsPerUnit;

            Rect inputRect = rectTransform.rect;

            // get the text alignment anchor point for the text in local space
            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);

            // Determine fraction of pixel to offset text mesh.
            Vector2 roundingOffset = PixelAdjustPoint(refPoint) - refPoint;

            //Last 4 verts are always a new line...
            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;            
        }

运行效果展示:
基于Unity2019版本的UGUI图文混排组件_第1张图片

需要详细代码的自取
链接:https://pan.baidu.com/s/1J4G9KtC6Mv_YlmdGndLn1Q
提取码:osua

你可能感兴趣的:(Unity备忘录,unity,unity3d)