精华内容
下载资源
问答
  • Unity超链接可点击文本组件
  • unity 超链接文本

    2021-10-21 16:27:07
    测试: Unity 2018.4 废话不多说,直接上代码: using System; using System.Collections; using System.Collections.Generic; using System.Text; using System.Text.RegularExpressions; using UnityEngine; ...

    测试: Unity 2018.4

    废话不多说,直接上代码:

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Text;
    using System.Text.RegularExpressions;
    using UnityEngine;
    using UnityEngine.Events;
    using UnityEngine.EventSystems;
    using UnityEngine.UI;
    
    /// <summary>
    /// 文本控件,支持超链接
    /// </summary>
    public class HyperlinkText : Text, IPointerClickHandler
    {
        /// <summary>
        /// 超链接信息类
        /// </summary>
        private class HyperlinkInfo
        {
            public int startIndex;
    
            public int endIndex;
    
            public string name;
    
            public readonly List<Rect> boxes = new List<Rect>();
        }
    
        /// <summary>
        /// 解析完最终的文本
        /// </summary>
        private string m_OutputText;
    
        /// <summary>
        /// 超链接信息列表
        /// </summary>
        private readonly List<HyperlinkInfo> m_HrefInfos = new List<HyperlinkInfo>();
    
        /// <summary>
        /// 文本构造器
        /// </summary>
        protected static readonly StringBuilder s_TextBuilder = new StringBuilder();
    
        [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>
        private static readonly Regex s_HrefRegex = new Regex(@"<a href=([^>\n\s]+)>(.*?)(</a>)", RegexOptions.Singleline);
    
        private HyperlinkText mHyperlinkText;
    
        protected override void Awake()
        {
            base.Awake();
            mHyperlinkText = GetComponent<HyperlinkText>();
        }
        protected override void OnEnable()
        {
            base.OnEnable();
            mHyperlinkText.onHrefClick.AddListener(OnHyperlinkTextInfo);
        }
    
        protected override void OnDisable()
        {
            base.OnDisable();
            mHyperlinkText.onHrefClick.RemoveListener(OnHyperlinkTextInfo);
        }
    
    
        public override void SetVerticesDirty()
        {
            base.SetVerticesDirty();
    #if UNITY_EDITOR
            if (UnityEditor.PrefabUtility.GetPrefabType(this) == UnityEditor.PrefabType.Prefab)
            {
                return;
            }
    #endif
            m_OutputText = GetOutputText(text);
    
        }
    
    
        protected override void OnPopulateMesh(VertexHelper toFill)
        {
            var orignText = m_Text;
            m_Text = m_OutputText;
            base.OnPopulateMesh(toFill);
            m_Text = orignText;
            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));
            }
        }
    
        /// <summary>
        /// 获取超链接解析后的最后输出文本
        /// </summary>
        /// <returns></returns>
        protected virtual string GetOutputText(string outputText)
        {
            s_TextBuilder.Length = 0;
            m_HrefInfos.Clear();
            var indexText = 0;
            foreach (Match match in s_HrefRegex.Matches(outputText))
            {
                s_TextBuilder.Append(outputText.Substring(indexText, match.Index - indexText));
    
                string str = s_TextBuilder.ToString();
                char[] array = str.ToCharArray();                //把字符串转化成字符数组
                IEnumerator enumerator = array.GetEnumerator();         //得到枚举器
                StringBuilder stringBuilder = new StringBuilder();
                while (enumerator.MoveNext())                         //开始枚举
                {
                    if ((char)enumerator.Current != ' ')         //向StringBuilder类对象添加非空格字符
                        stringBuilder.Append(enumerator.Current.ToString());
                }
    
                var group = match.Groups[1];
                var hrefInfo = new HyperlinkInfo
                {
                    startIndex = stringBuilder.Length * 4, // 超链接里的文本起始顶点索引
                    endIndex = (stringBuilder.Length + match.Groups[2].Length - 1) * 4 + 3 ,
                    name = group.Value
                };
    
                m_HrefInfos.Add(hrefInfo);
                s_TextBuilder.Append("<color=blue>");  // 超链接颜色
                s_TextBuilder.Append(match.Groups[2].Value);
                s_TextBuilder.Append("</color>");
                indexText = match.Index + match.Length;
            }
            s_TextBuilder.Append(outputText.Substring(indexText, outputText.Length - indexText));
            return s_TextBuilder.ToString();
        }
    
        /// <summary>
        /// 点击事件检测是否点击到超链接文本
        /// </summary>
        /// <param name="eventData"></param>
        public void OnPointerClick(PointerEventData eventData)
        {
            Vector2 lp = Vector2.zero;
            
            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>
        /// <param name="info">回调信息</param>
        private void OnHyperlinkTextInfo(string info)
        {
            Debug.Log("超链接信息:" + info);
            Application.OpenURL(info);
        }
    }

    展开全文
  • 本资源为unity中uguiText文本插入超链接(即 网址,图片等),简单好用,只需要将manager类放到父物体身上,将initText放到Text身上,即可
  • 图中4个DC:Unity本身1个,文本整体只有1个,0x02动态加载图片1个,0x03加载的动画1个 效果图: 输入内容: New GText 测试[AA]ceshi 测试[AB|36#dianji]ceshi自定义大小且可点击表情 测试[a|40#dianji]ceshi自定义...
  • Unity Text 超链接插件

    2015-10-09 22:56:03
    this is limited version of Text Action Pro (no anim support, no fade duration, no phase for curve, no example scene due to reaching 2MB limit, but added small documentation from TAPro) + contemporary ...
  • Emoji和用于Unity UGUI的超链接文本,继承自UGUI中的文本组件,实现超链接和图文混排, 参考了 相较于GText修改了: 新增点击超链接范围外的一部分 优化下划线表现 新增了超链接颜色渐变 删除了单独的下划线 删除...
  • Unity 超链接 Text

    2022-01-26 15:55:59
    Unity 超链接 Text

    Unity 超链接 Text

    之前用的是https://github.com/akof1314/uGUI_LinkImageText这个控件,结果发现点击事件是不对的。我将包围框显示出来后它是这样一种情况

    包围框显示

    从图片可以看出这个包围框是混乱的,那就难怪点击事件不准了。经排查发现是包围框的起始和结束的Index计算有错误。

    详情是这样的,这个功能的本质是截取网址这一段,拿到他的开始和结束的Index,然后遍历Text渲染顶点的时候以开始Index为左,结束Index为右,生成一个包围框(有换行另处理)。那么这个包围框就是我们点击网址的相应区域。

    而原版在计算这个Index的时候出现了失误,因为忽略了两个关键点:

    1. 富文本的语法代码没有渲染顶点,需剔除Index计算
    2. 空格、回车没有渲染顶点,需剔除Index计算
      也就是说,对于:
    Baidu 网址:
    <a href=https://www.baidu.com/>Baidu网址</a>
    
    google 网址:
    <a href=https://www.google.com/>google网址</a>
    
    Baidu URL:
    <a href=https://www.baidu.com/>https://www.baidu.com/</a>
    
    google URL:
    <a href=https://www.google.com/>https://www.google.com/</a>
    
    

    这样的文本,我们需要剔除富文本html语法和空格、换行符后才能用来计算Index,就像这样:

    Baidu网址:Baidu网址google 网址:google网址BaiduURLhttps://www.baidu.com/googleURL:https://www.google.com/
    

    把所有不参与顶点计算的元素去掉才行。

    如果想要改颜色,根据语法需要加标签,如:

    Baidu 网址:
    <a href=https://www.baidu.com/><color=red>Baidu网址</color></a>
    
    google 网址:
    <a href=https://www.google.com/>google网址</a>
    
    Baidu URL:
    <a href=https://www.baidu.com/>https://www.baidu.com/</a>
    
    google URL:
    <a href=https://www.google.com/>https://www.google.com/</a>
    

    其中第一条的baidu网址显示就是红色的,当然,在计算Index的时候也要把标签刨除掉

    显示如图,可以看到下面的包围框显示是完全正常的

    修正后的包围框显示

    完整代码:

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Text;
    using System.Text.RegularExpressions;
    using UnityEngine;
    using UnityEngine.Events;
    using UnityEngine.EventSystems;
    using UnityEngine.UI;
    
    /// <summary>
    /// TextHyperlink 支持Unity超链接富文本语法
    /// 例如<a href=https://aws.amazon.com/privacy/>https://aws.amazon.com/privacy/</a>
    /// 带颜色的超链接:
    /// <a href=https://aws.amazon.com/privacy/><color=#FF0000>https://aws.amazon.com/privacy/</color></a>
    /// </summary>
    public class TextHyperlink : Text, IPointerClickHandler
    {
        /// <summary>
        /// 超链接信息类
        /// </summary>
        private class HyperlinkInfo
        {
            //起始Index
            public int StartIndex;
            //结束Index
            public int EndIndex;
            //内容
            public string Name;
            //包围框
            public List<Rect> BoxList = new List<Rect>();
        }
    
        #region 私有变量
        //超链接正则
        private static Regex _hrefRegex = new Regex(@"<a href=([^>\n\s]+)>(.*?)(</a>)", RegexOptions.Singleline);
        //颜色正则
        private static Regex _colorRegex = new Regex(@"<color=([^>\n\s]+)>(.*?)(</color>)", RegexOptions.Singleline);
        //超链接信息列表
        private List<HyperlinkInfo> _hyperlinkInfoList = new List<HyperlinkInfo>();
        //显示包围盒范围,想用的话输入true
        private bool _showTestBound = true;
        #endregion
    
        #region 公有变量
    
        #endregion
    
        #region 生命周期
        protected override void OnPopulateMesh(VertexHelper toFill)
        {
            base.OnPopulateMesh(toFill);
    
            InitHyperlinkInfo();
    
            InitHyperlinkBox(toFill);
        }
    
        protected override void Start()
        {
            if (_showTestBound)
            {
                AddVisibleBound();
            }
        }
        #endregion
    
        #region 公有方法
    
        #endregion
    
        #region 动作
        public void OnPointerClick(PointerEventData eventData)
        {
            Vector2 localPoint;
            RectTransformUtility.ScreenPointToLocalPointInRectangle(
                rectTransform, eventData.position, eventData.pressEventCamera, out localPoint);
    
            foreach (HyperlinkInfo hyperlinkInfo in _hyperlinkInfoList)
            {
                var boxeList = hyperlinkInfo.BoxList;
                for (var i = 0; i < boxeList.Count; ++i)
                {
                    if (boxeList[i].Contains(localPoint))
                    {
                        //打开网址
                        //this.Log("TextHyperlink", hyperlinkInfo.Name);
                        Application.OpenURL(hyperlinkInfo.Name);
                        return;
                    }
                }
            }
        }
        #endregion
    
        #region 私有方法
        /// <summary>
        /// 初始化连接信息
        /// </summary>
        private void InitHyperlinkInfo()
        {
            //这个值不用,就是个存根。要的是执行后面那个方法
            string outputText = GetOutputText(text);
        }
    
        /// <summary>
        /// 初始化连接包围框
        /// </summary>
        /// <param name="toFill"></param>
        private void InitHyperlinkBox(VertexHelper toFill)
        {
            UIVertex vert = new UIVertex();
    
            // 处理超链接包围框
            foreach (var hrefInfo in _hyperlinkInfoList)
            {
                hrefInfo.BoxList.Clear();
    
                //一个字符是四个顶点,所以Index要乘以4
                int startVertex = hrefInfo.StartIndex * 4;
                int endVertex = hrefInfo.EndIndex * 4;
    
                if (startVertex >= toFill.currentVertCount)
                {
                    continue;
                }
    
                // 将超链接里面的文本顶点索引坐标加入到包围框
                toFill.PopulateUIVertex(ref vert, startVertex);
                var pos = vert.position;
                var bounds = new Bounds(pos, Vector3.zero);
                for (int i = startVertex; i < endVertex; i++)
                {
                    if (i >= toFill.currentVertCount)
                    {
                        break;
                    }
    
                    toFill.PopulateUIVertex(ref vert, i);
                    pos = vert.position;
                    if (pos.x < bounds.min.x) // 换行重新添加包围框
                    {
                        hrefInfo.BoxList.Add(new Rect(bounds.min, bounds.size));
                        bounds = new Bounds(pos, Vector3.zero);
                    }
                    else
                    {
                        bounds.Encapsulate(pos); // 扩展包围框
                    }
                }
    
                hrefInfo.BoxList.Add(new Rect(bounds.min, bounds.size));
            }
        }
    
        /// <summary>
        /// 获取超链接解析后的最后输出文本
        /// </summary>
        /// <returns></returns>
        private string GetOutputText(string outputText)
        {
            StringBuilder stringBuilder = new StringBuilder();
    
            _hyperlinkInfoList.Clear();
    
            int strIndex = 0;
    
            foreach (Match match in _hrefRegex.Matches(outputText))
            {
                string appendStr = outputText.Substring(strIndex, match.Index - strIndex);
                stringBuilder.Append(appendStr);
    
                //空格和回车没有顶点渲染,所以要去掉
                stringBuilder = stringBuilder.Replace(" ", "");
                stringBuilder = stringBuilder.Replace("\n", "");
    
                int startIndex = stringBuilder.Length;
    
                //第一个是连接url,第二个是连接文本,跳转用url,计算index用文本
                Group urlGroup = match.Groups[1];
                Group titleGroup = match.Groups[2];
    
                //如果有Color语法嵌套,则还要继续扒,知道吧最终文本扒出来
                Match colorMatch = _colorRegex.Match(titleGroup.Value);
    
                if (colorMatch.Groups.Count > 3)
                {
                    titleGroup = colorMatch.Groups[2];
                }
    
                stringBuilder.Append(titleGroup.Value);
    
                HyperlinkInfo hyperlinkInfo = new HyperlinkInfo
                {
                    StartIndex = startIndex, 
                    EndIndex = (startIndex + titleGroup.Length),
                    Name = urlGroup.Value
                };
    
                strIndex = match.Index + match.Length;
                _hyperlinkInfoList.Add(hyperlinkInfo);
            }
            stringBuilder.Append(outputText.Substring(strIndex, outputText.Length - strIndex));
            return stringBuilder.ToString();
        }
    
        /// <summary>
        /// 添加可视包围框(测试用方法)
        /// </summary>
        private void AddVisibleBound()
        {
            int index = 0;
    
            foreach (var hyperLinkInfo in _hyperlinkInfoList)
            {
                Color color = new Color(UnityEngine.Random.Range(0f, 1f), UnityEngine.Random.Range(0f, 1f), UnityEngine.Random.Range(0f, 1f), 0.2f);
                index++;
                foreach (Rect rect in hyperLinkInfo.BoxList)
                {
                    GameObject gameObject = new GameObject();
                    gameObject.name = string.Format("GOBoundBox[{0}]", hyperLinkInfo.Name);
                    gameObject.SetParent(this.gameObject);
    
                    RectTransform rectTransform = gameObject.AddComponent<RectTransform>();
                    rectTransform.sizeDelta = rect.size;
                    rectTransform.localPosition = new Vector3(rect.position.x + rect.size.x / 2, rect.position.y + rect.size.y / 2, 0);
    
                    Image image = gameObject.AddComponent<Image>();
                    image.color = color;
                    image.raycastTarget = false;
                }
            }
        }
        #endregion
    }
    
    
    展开全文
  • using System; using System.Collections.Generic; using System.Text; using System.Text.RegularExpressions; using UnityEngine; using UnityEngine.Events;.../// 文本控件,支持超链接 /// </summary
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Text.RegularExpressions;
    using UnityEngine;
    using UnityEngine.Events;
    using UnityEngine.EventSystems;
    using UnityEngine.UI;
    
    /// <summary>
    /// 文本控件,支持超链接
    /// </summary>
    public class HyperlinkText : Text, IPointerClickHandler
    {
        /// <summary>
        /// 超链接信息类
        /// </summary>
        private class HyperlinkInfo
        {
            public int startIndex;
    
            public int endIndex;
    
            public string name;
    
            public readonly List<Rect> boxes = new List<Rect>();
        }
    
        /// <summary>
        /// 解析完最终的文本
        /// </summary>
        private string m_OutputText;
    
        /// <summary>
        /// 超链接信息列表
        /// </summary>
        private readonly List<HyperlinkInfo> m_HrefInfos = new List<HyperlinkInfo>();
    
        /// <summary>
        /// 文本构造器
        /// </summary>
        protected static readonly StringBuilder s_TextBuilder = new StringBuilder();
    
        [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>
        private static readonly Regex s_HrefRegex = new Regex(@"<a href=([^>\n\s]+)>(.*?)(</a>)", RegexOptions.Singleline);
    
        private HyperlinkText mHyperlinkText;
    
        
        [SerializeField]
        public string mName1 = "《服务协议》";
        
        
        [SerializeField]
        public string mName2 = "《隐私政策》";
        public string GetHyperlinkInfo
        {
            get { return string.Format("请你务必审慎阅读、充分理解“服务协议”和“隐私政策”各条款,包括但不限于:为了向您提供AR扫描模型服务,我们需要获取您移动设备相机" +
                                       "权限。你可阅读<a href={0:link}>{1:name}</a>和<a href={2:link}>{3:name}</a>了解详细信息。" +
                                       "如你同意,请点击“同意”开始接受我们的服务。", "http://www.baidu.com", mName1, "http://www.google.com", mName2); }
        }
    
        protected override void Awake()
        {
            base.Awake();
            mHyperlinkText = GetComponent<HyperlinkText>();
        }
        protected override void OnEnable()
        {
            base.OnEnable();
            mHyperlinkText.onHrefClick.AddListener(OnHyperlinkTextInfo);
        }
    
        protected override void OnDisable()
        {
            base.OnDisable();
            mHyperlinkText.onHrefClick.RemoveListener(OnHyperlinkTextInfo);
        }
    
    
        public override void SetVerticesDirty()
        {
            base.SetVerticesDirty();
    #if UNITY_EDITOR
            if (UnityEditor.PrefabUtility.GetPrefabType(this) == UnityEditor.PrefabType.Prefab)
            {
                return;
            }
    #endif
            //  m_OutputText = GetOutputText(text);
            text = GetHyperlinkInfo;
            m_OutputText = GetOutputText(text);
    
        }
    
    
        protected override void OnPopulateMesh(VertexHelper toFill)
        {
            var orignText = m_Text;
            m_Text = m_OutputText;
            base.OnPopulateMesh(toFill);
            m_Text = orignText;
            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));
            }
        }
    
        /// <summary>
        /// 获取超链接解析后的最后输出文本
        /// </summary>
        /// <returns></returns>
        protected virtual string GetOutputText(string outputText)
        {
            s_TextBuilder.Length = 0;
            m_HrefInfos.Clear();
            var indexText = 0;
            foreach (Match match in s_HrefRegex.Matches(outputText))
            {
                s_TextBuilder.Append(outputText.Substring(indexText, match.Index - indexText));
                s_TextBuilder.Append("<color='#0080FF'>");  // 超链接颜色
    
                var group = match.Groups[1];
                var hrefInfo = new HyperlinkInfo
                {
                    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(outputText.Substring(indexText, outputText.Length - indexText));
            return s_TextBuilder.ToString();
        }
    
        /// <summary>
        /// 点击事件检测是否点击到超链接文本
        /// </summary>
        /// <param name="eventData"></param>
        public void OnPointerClick(PointerEventData eventData)
        {
            Vector2 lp = Vector2.zero;
            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>
        /// <param name="info">回调信息</param>
        private void OnHyperlinkTextInfo(string info)
        {
            Debug.Log("超链接信息:" + info);
        }
    
    }
    
    
    展开全文
  • 在网上原有的继承于UGUI的Text基础上根据正则表达式找出表情标记文本替换为表情图片并实现序列帧动画的基础上扩展了下划线和超链接功能,跟UGUI的下划线和超链接功能一样
  • Unity添加超链接文本

    千次阅读 2019-11-04 21:29:43
    原文中正则表达式"<a href=([^>\n\s]+)>(.*?)(</a>)"的s前面只有一条\,实际应该是两条,这样才...扩展Text组件,使用时直接添加HyperlinkText 组件即可,超链接格式为<a href="text">text&l...

    原文在这里:https://www.jianshu.com/p/76c45c2f6383

    原文中正则表达式"<a href=([^>\n\s]+)>(.*?)(</a>)"的s前面只有一条\,实际应该是两条,这样才能够匹配空格。

    扩展Text组件,使用时直接添加HyperlinkText 组件即可,超链接格式为<a href="text">text</a>

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Text.RegularExpressions;
    using UnityEngine;
    using UnityEngine.Events;
    using UnityEngine.EventSystems;
    using UnityEngine.UI;
    
    /// <summary>
    /// 文本控件,支持超链接
    /// </summary>
    public class HyperlinkText : Text, IPointerClickHandler
    {
        /// <summary>
        /// 超链接信息类
        /// </summary>
        private class HyperlinkInfo
        {
            public int startIndex;
    
            public int endIndex;
    
            public string name;
    
            public readonly List<Rect> boxes = new List<Rect>();
        }
    
        /// <summary>
        /// 解析完最终的文本
        /// </summary>
        private string m_OutputText;
    
        /// <summary>
        /// 超链接信息列表
        /// </summary>
        private readonly List<HyperlinkInfo> m_HrefInfos = new List<HyperlinkInfo>();
    
        /// <summary>
        /// 文本构造器
        /// </summary>
        protected static readonly StringBuilder s_TextBuilder = new StringBuilder();
    
        [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>
        private static readonly Regex s_HrefRegex = new Regex(@"<a href=([^>\n\\s]+)>(.*?)(</a>)", RegexOptions.Singleline);
        
        public override void SetVerticesDirty()
        {
            base.SetVerticesDirty();
    #if UNITY_EDITOR
            if (UnityEditor.PrefabUtility.GetPrefabAssetType(this) == UnityEditor.PrefabAssetType.Model)
            {
                return;
            }
    #endif
            m_OutputText = GetOutputText(text);
        }
        protected override void OnPopulateMesh(VertexHelper toFill)
        {
            var orignText = m_Text;
            m_Text = m_OutputText;
            base.OnPopulateMesh(toFill);
            m_Text = orignText;
            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));
            }
        }
        /// <summary>
        /// 获取超链接解析后的最后输出文本
        /// </summary>
        /// <returns></returns>
        protected virtual string GetOutputText(string outputText)
        {
            s_TextBuilder.Length = 0;
            m_HrefInfos.Clear();
            var indexText = 0;
            foreach (Match match in s_HrefRegex.Matches(outputText))
            {
                s_TextBuilder.Append(outputText.Substring(indexText, match.Index - indexText));
                s_TextBuilder.Append("<color=blue>");  // 超链接颜色
    
                var group = match.Groups[1];
                var hrefInfo = new HyperlinkInfo
                {
                    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(outputText.Substring(indexText, outputText.Length - indexText));
            return s_TextBuilder.ToString();
        }
        /// <summary>
        /// 点击事件检测是否点击到超链接文本
        /// </summary>
        /// <param name="eventData"></param>
        public void OnPointerClick(PointerEventData eventData)
        {
            Vector2 lp = Vector2.zero;
            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;
                    }
                }
            }
        }
    }

    下面是如何访问回调函数

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    
    public class Test: MonoBehaviour
    {    
        // Start is called before the first frame update
        void Start()
        {
            transform.GetComponent<HyperlinkText>().onHrefClick.AddListener(OnHrefClick);//监听文本中的超链接的点击事件
        }    
        
        /// <summary>
        /// 文本超链接的回调函数
        /// </summary>
        /// <param name="hrefName"></param>
        private void OnHrefClick(string hrefName)
        {
            Debug.Log("点击了超链接:" + hrefName);                               
        }    
    }

    这个脚本有一个问题,就是HyperlinkText计算长度时会把整个超链接的长度计算在内,而不是仅计算超链接中显示的文本,所以有些情况超链接会失效

    展开全文
  • Unity Text 插入超链接

    万次阅读 多人点赞 2015-10-12 18:52:19
    Unity 新 UI 系统中的 Text 组件支持富文本标签,标签包括 b(黑体)、i(斜体)、size(大小)、color(颜色),并不支持超链接以及超链接点击。之前一篇实现了简单的插入图片方法,见《Unity Text 插入图片》。...
  • unity3dText实现超链接

    千次阅读 2017-06-30 15:43:00
    if (UnityEditor.PrefabUtility.GetPrefabType(this) == UnityEditor.PrefabType.Prefab) { return; } #endif // m_OutputText = GetOutputText(text); text = GetHyperlinkInfo; m_OutputText = ...
  • Unity Text 实现文本超链接 由于Unity2019.1.5f1及更高版本不再存储Text的完整vertex信息,不支持unity2019.1.5f1及更高版本,所以以前的脚本不适用新的Text。因此,重新实现文本超链接功能。
  • Unity TextMeshProUGUI点击超链接跳转

    千次阅读 2020-08-25 16:48:56
    using System.Collections; using System.Collections.Generic; using TMPro; using UnityEngine; using UnityEngine.EventSystems; ...public class TestClickRichText : MonoBehaviour, IPointerClickHandler ...
  • Unity 图文混排超链接图片均可点击

    千次阅读 2018-03-12 16:04:50
    文本控件,支持超链接、图片 /// [AddComponentMenu( "UI/LinkImageText" , 10 )] public class LinkImageText : RichText, IPointerClickHandler { /// /// 解析完最终的文本 /// ...
  • Unity UGUI图文混排(六) -- 超链接

    千次阅读 2016-10-25 11:14:44
    图文混排更新到超链接这儿,好像也差不多了,不过就在最后一点,博主也表现得相当不专业,直接整合了山中双木林同学提供的超链接的解决方案,博主甚至没来得及细看就直接复制了,但感觉还是挺好用的。 博主已经将...
  • Unity NGUI 制作URL超链接点击打开网页

    千次阅读 2018-03-01 17:12:48
    1、添加Lable  菜单NGUI-create-lable ...3、为Lable 添加Box Collider组件 勾选 Is trigger 4、为Lable添加OpenURLOnClick ...文字超链接显示格式:[url=http://www.tasharen.com/][u]clickable hyperlinks[/u][/url]
  • Unity Text加入超链接

    千次阅读 2015-12-20 18:07:15
    Unity 新 UI 系统中的 Text 组件支持富文本标签,标签包括 b(黑体)、i(斜体)、size(大小)、color(颜色),并不支持超链接以及超链接点击。之前一篇实现了简单的插入图片方法,见《Unity Text 插入图片》...
  • #if UNITY_EDITOR if (UnityEditor.PrefabUtility.GetPrefabType(this) == UnityEditor.PrefabType.Prefab) { return; } #endif // m_OutputText = GetOutputText(text); text = GetHyperlinkInfo; m_OutputText = ...
  • Unity ugui下划线underline实现

    千次阅读 2019-11-15 14:23:42
    unity ugui下划线underline实现 效果图 场景ui结构 适配代码,使下划线根据文本长度自动增长 using UnityEngine; using UnityEngine.UI; /// <summary> /// 只计算宽 /// </summary> public class ...
  • Unity UGUI兼容超链接富文本

    千次阅读 2021-12-23 10:58:05
    超链接格式:<a href=www.baidu.com>百度</a> using System; using System.Collections.Generic; using System.Text; using System.Text.RegularExpressions; using UnityEngine; using UnityEngine....
  • Unity UGUI实现图文混排组件——EmojiText(支持图标,动态表情,按钮,超链接
  • 超链接按钮样式

    2018-09-10 16:12:00
    .myLinkA { text-decoration: none; font-size: 12px; background-color: #4CAF50; border: none; padding: 15px 32px; text-align: center; display: inline-block; font-size: 16px; color: white;...
  • Unity UGUI Text实现超链接点击

    千次阅读 2020-02-18 16:19:48
    一开始我在网上找这种实现方法,但是发现的确有很多,但是都有问题乱七八糟的,我就修改然后整理成可以用的了。OK,Fine.就这样。 首先新建一个Text,然后删掉Text组件,并且把下面的代码拷贝然后挂载到新建的Text上。...
  • public Text text; public bool AutoSize = false; private RectTransform rectTrans; void Awake() { rectTrans = transform.GetComponent<RectTransform>...public void OnTextChange(string val...
  • 文本内超链接(附下划线),文本内插入图片
  • unity 点击button(按钮)跳转链接

    千次阅读 2020-04-01 14:09:44
    url = "www.baidu.com"; //1 Application.OpenURL (url); //2 Help.BrowseURL(url); //3 System.Diagnostics.Process.Start("https://www.baidu.com/");

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 546
精华内容 218
关键字:

unity超链接