• Unity UGUI图文混排(六) -- 超链接


    图文混排更新到超链接这儿,好像也差不多了,不过就在最后一点,博主也表现得相当不专业,直接整合了山中双木林同学提供的超链接的解决方案,博主甚至没来得及细看就直接复制了,但感觉还是挺好用的。

    博主已经将超链接的功能直接整合到了之前的InlineText和InlineSpriteText的两个脚本中


    1.定义超链接的正则表达式和事件监听

    #region 超链接
        /// <summary>
        /// 超链接信息列表
        /// </summary>
        private readonly List<HrefInfo> m_HrefInfos = new List<HrefInfo>();
    
        /// <summary>
        /// 文本构造器
        /// </summary>
        private static readonly StringBuilder s_TextBuilder = new StringBuilder();
    
        /// <summary>
        /// 超链接正则
        /// </summary>
        private static readonly Regex s_HrefRegex =
            new Regex(@"<a href=([^>
    s]+)>(.*?)(</a>)", RegexOptions.Singleline);
    
        [System.Serializable]
        public class HrefClickEvent : UnityEvent<string> { }
    
        [SerializeField]
        private HrefClickEvent m_OnHrefClick = new HrefClickEvent();
    
        /// <summary>
        /// 超链接点击事件
        /// </summary>
        public HrefClickEvent onHrefClick
        {
            get { return m_OnHrefClick; }
            set { m_OnHrefClick = value; }
        }
    
        /// <summary>
        /// 获取超链接解析后的最后输出文本
        /// </summary>
        /// <returns></returns>
        protected string GetOutputText()
        {
            s_TextBuilder.Length = 0;
            m_HrefInfos.Clear();
            var indexText = 0;
            foreach (Match match in s_HrefRegex.Matches(text))
            {
                s_TextBuilder.Append(text.Substring(indexText, match.Index - indexText));
                s_TextBuilder.Append("<color=blue>");  // 超链接颜色
    
                var group = match.Groups[1];
                var hrefInfo = new HrefInfo
                {
                    startIndex = s_TextBuilder.Length * 4, // 超链接里的文本起始顶点索引
                    endIndex = (s_TextBuilder.Length + match.Groups[2].Length - 1) * 4 + 3,
                    name = group.Value
                };
                m_HrefInfos.Add(hrefInfo);
    
                s_TextBuilder.Append(match.Groups[2].Value);
                s_TextBuilder.Append("</color>");
                indexText = match.Index + match.Length;
            }
            s_TextBuilder.Append(text.Substring(indexText, text.Length - indexText));
            return s_TextBuilder.ToString();
        }
    
        /// <summary>
        /// 点击事件检测是否点击到超链接文本
        /// </summary>
        /// <param name="eventData"></param>
        public void OnPointerClick(PointerEventData eventData)
        {
            Vector2 lp;
            RectTransformUtility.ScreenPointToLocalPointInRectangle(
                rectTransform, eventData.position, eventData.pressEventCamera, out lp);
    
            foreach (var hrefInfo in m_HrefInfos)
            {
                var boxes = hrefInfo.boxes;
                for (var i = 0; i < boxes.Count; ++i)
                {
                    if (boxes[i].Contains(lp))
                    {
                        m_OnHrefClick.Invoke(hrefInfo.name);
                        return;
                    }
                }
            }
        }
    
        /// <summary>
        /// 超链接信息类
        /// </summary>
        private class HrefInfo
        {
            public int startIndex;
    
            public int endIndex;
    
            public string name;
    
            public readonly List<Rect> boxes = new List<Rect>();
        }
        #endregion
    2.在文本绘制完成后处理超链接的包围盒

     #region 处理超链接的包围盒
            // 处理超链接包围框
            UIVertex vert = new UIVertex();
            foreach (var hrefInfo in m_HrefInfos)
            {
                hrefInfo.boxes.Clear();
                if (hrefInfo.startIndex >= toFill.currentVertCount)
                {
                    continue;
                }
    
                // 将超链接里面的文本顶点索引坐标加入到包围框
                toFill.PopulateUIVertex(ref vert, hrefInfo.startIndex);
                var pos = vert.position;
                var bounds = new Bounds(pos, Vector3.zero);
                for (int i = hrefInfo.startIndex, m = hrefInfo.endIndex; i < m; i++)
                {
                    if (i >= toFill.currentVertCount)
                    {
                        break;
                    }
    
                    toFill.PopulateUIVertex(ref vert, i);
                    pos = vert.position;
                    if (pos.x < bounds.min.x) // 换行重新添加包围框
                    {
                        hrefInfo.boxes.Add(new Rect(bounds.min, bounds.size));
                        bounds = new Bounds(pos, Vector3.zero);
                    }
                    else
                    {
                        bounds.Encapsulate(pos); // 扩展包围框
                    }
                }
                hrefInfo.boxes.Add(new Rect(bounds.min, bounds.size));
            }
            #endregion
    3.看一下文中中超链接的输入规则


    4.简单写了一个测试脚本,用来监听点击事件

    using UnityEngine;
    using System.Collections;
    
    public class TestClickInlineText : MonoBehaviour {
        private InlieText _text;
        
        void Awake()
        {
            _text = GetComponent<InlieText>();
        }
    
        void OnEnable()
        {
            _text.onHrefClick.AddListener(OnHrefClick);
        }
    
        void OnDisable()
        {
            _text.onHrefClick.RemoveListener(OnHrefClick);
        }
    
        private void OnHrefClick(string hrefName)
        {
            Debug.Log("点击了 " + hrefName);
          //  Application.OpenURL("www.baidu.com");
        }
    }
    
    5.运行截图:


    6.更新速度实在太慢,为了早点完结图文混排,这里的功能是复制的,有什么疑问的话,可以再讨论,这里的功能也就更新得差不多了,最后再给一个最新的源码链接,短时间没有特殊的功能或者bug,就不打算再更新了

    工程源码链接:https://github.com/coding2233/TextInlineSprite


  • 相关阅读:
    Android 开发工具类 19_NetworkStateReceiver
    Android 开发工具类 18_NetWorkUtil
    Sticky Footer (让页脚永远停靠在页面底部,而不是根据绝对位置)
    min-height最小高度的实现(兼容IE6、IE7、FF)(解决IE6不兼容min-height)
    不同浏览器设置背景透明度
    讨论内外边距对行内元素是否起作用,则要对行内替换元素和行内非替换元素分别讨论:
    超链接访问过后hover样式就不出现的问题
    解决:子元素设置margin-top,父元素也受影响的问题
    制作0.5px像素的细条
    去掉inline-block元素间隙的几种方法
  • 原文地址:https://www.cnblogs.com/liang123/p/6325845.html
Copyright © 2020-2023  润新知