码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • Unity3D Text使用超链接跳转事件


    系列文章目录

    Unity工具


    文章目录

    • 系列文章目录
    • 👉前言
    • 👉一、第一种使用TextMeshPro加入超链接
    • 👉二、继承Text组件,重载OnPopulateMesh方法
    • 👉三.壁纸分享
    • 👉总结


    👉前言

    有时候会用到跳转的问题,所以添加一个跳转的方法,方便使用,简单记录一下
    主要是两种方法,一种是使用 TextMeshPro,另一种是继承Text组件,重载OnPopulateMesh方法
    大家好,我是心疼你的一切,不定时更新Unity开发技巧,觉得有用记得一键三连哦。
    欢迎点赞评论哦.
    下面就让我们进入正文吧 !


    提示:以下是本篇文章正文内容,下面案例可供参考

    👉一、第一种使用TextMeshPro加入超链接

    这种就比较简单了,因为它本来就支持超链接,只需要使用标签link即可

    标签类型如下:

    link>//超链接标签
    <#0C86BA>color>//颜色标签
    <u>u>//下划线标签
    
    

    TMP设置如下
    TMP设置为canvas下面,创建空物体,添加TextMeshPro-Text(UI)组件即可
    如果想要输入中文需要自己设置字体包要不然输入不了中文的(切记)
    Text Input显示的示例:

    <u><#0076FF>csdn urlu>color>link>
    

    在这里插入图片描述

    效果图如下所示
    在这里插入图片描述

    新建脚本TMPTextLink.cs开始编写代码,代码如下:

    using System.Collections;
    using System.Collections.Generic;
    using TMPro;
    using UnityEngine;
    using UnityEngine.EventSystems;
    
    public class TMPTextLink : MonoBehaviour, IPointerClickHandler
    {
        private TextMeshProUGUI m_TextMeshPro;
    
        void Awake()
        {
            m_TextMeshPro = this.transform.GetComponent<TextMeshProUGUI>();
        }
    
        void Start()
        {
    
        }
        public void OnPointerClick(PointerEventData eventData)
        {
            int linkIndex = TMP_TextUtilities.FindIntersectingLink(m_TextMeshPro, Input.mousePosition, eventData.pressEventCamera);
            TMP_LinkInfo linkInfo = m_TextMeshPro.textInfo.linkInfo[linkIndex];
            RectTransformUtility.ScreenPointToLocalPointInRectangle(m_TextMeshPro.rectTransform, eventData.position, eventData.pressEventCamera, out var worldPointInRectangle);
            switch (linkInfo.GetLinkID())
            {
                //要跟标签里面的id一致
                case "linkkkkkk":
                    Debug.Log("点击了linkkkkkk的超链接");
                    Application.OpenURL("https://blog.csdn.net/qq_42603590?type=blog");
                    break;
            }
        }
    }
    
    

    最后效果自行测试吧,点击之后就会跳转到博客页面,并且会打印
    在这里插入图片描述

    👉二、继承Text组件,重载OnPopulateMesh方法

    1.使用正则表达式获取超链接标签

    //获取以开头,以a>结束的内容。
    <a link=([^>\n\s]+)>(.*?)(a>)
    
    

    2.新建一个LinkText.cs脚本,编辑如下 ,脚本继承Text,IPointerClickHandler
    代码如下:

    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;
    
    /// 
    /// 超链接信息类
    /// 
    /// 
    [Serializable]
    public class HyperlinkInfo
    {
        public int startIndex;
        public int endIndex;
        public string name;
        public readonly List<Rect> boxes = new List<Rect>();
    }
    public class LinkText : Text, IPointerClickHandler
    {
        /// 
        /// 解析完最终的文本
        /// 
        private string m_OutputText;
        /// 
        /// 超链接信息列表
        /// 
        private readonly List<HyperlinkInfo> _mLinkInfos = new List<HyperlinkInfo>();
        /// 
        /// 文本构造器
        /// 
        protected static readonly StringBuilder s_TextBuilder = new StringBuilder();
        /// 
        /// 超链接正则表达式
        /// 
        private static readonly Regex s_HrefRegex = new Regex(@"\n\s]+)>(.*?)()", RegexOptions.Singleline);
        /// 
        /// 文本超链接控件
        /// 
        private LinkText mHyperlinkText;
    
    
        protected override void Awake()
        {
            base.Awake();
            mHyperlinkText = GetComponent<LinkText>();
        }
    
        #region 回调事件
        public Action<string> onLinkClick;
        /// 
        /// 点击事件检测是否点击到超链接文本
        /// 
        /// 
        public void OnPointerClick(PointerEventData eventData)
        {
            RectTransformUtility.ScreenPointToLocalPointInRectangle(
                rectTransform, eventData.position, eventData.pressEventCamera, out var lp);
    
            foreach (var info in _mLinkInfos)
            {
                var boxes = info.boxes;
                for (var i = 0; i < boxes.Count; ++i)
                {
                    if (!boxes[i].Contains(lp)) continue;
                    onLinkClick?.Invoke(info.name);
                    return;
                }
            }
        }
        #endregion
    
        #region 生成超链接
        /// 
        /// 重新渲染网格
        /// 
        public override void SetVerticesDirty()
        {
            base.SetVerticesDirty();
            m_OutputText = GetOutputText(text);
        }
    
        /// 
        /// 处理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 _mLinkInfos)
            {
                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));
            }
        }
    
        /// 
        /// 获取超链接解析后的最后输出文本
        /// 
        /// 
        protected virtual string GetOutputText(string outputText)
        {
            s_TextBuilder.Length = 0;
            _mLinkInfos.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
                };
    
                _mLinkInfos.Add(hrefInfo);
                s_TextBuilder.Append("");  // 超链接颜色
                s_TextBuilder.Append(match.Groups[2].Value);
                s_TextBuilder.Append("");
                indexText = match.Index + match.Length;
            }
            s_TextBuilder.Append(outputText.Substring(indexText, outputText.Length - indexText));
            return s_TextBuilder.ToString();
        }
        #endregion
    }
    
    

    2.新建一个空物体把LinkText组件添加进去
    3.最后再写一个调用脚本LinkTextOnlick.cs也挂到这个空物体上即可
    代码如下:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class LinkTextOnlick : MonoBehaviour
    {
        public LinkText linkText;
        void Start()
        {
            // 动态显示文本
            linkText.text = "文本测试:我的博客";
            // 绑定事件
            linkText.onLinkClick = (info) => onclick(info);
        }
    
        void onclick(string info)
        {
            Debug.Log(info);
            Application.OpenURL(info);
        }
    }
    
    

    记得挂上去之后拖一下LinkText组件,或者在start里面写一个查找都行,看自己心情喽
    之后运行点击"我的博客即可跳转链接了哦"
    4.运行效果图如下
    在这里插入图片描述

    👉三.壁纸分享

    请添加图片描述
    请添加图片描述


    👉总结

    本次总结的就是Text实现超链接跳转,有需要会继续添加新的
    如能帮助到你,就帮忙点个赞吧,三连更好哦,谢谢
    你的点赞就是对博主的支持,有问题记得留言评论哦!
    不定时更新Unity开发技巧,觉得有用记得一键三连哦。么么哒

  • 相关阅读:
    长城人寿童星守护少儿重疾险怎么样?好不好?
    【JAVA】编码表,字符流,对象流,其他流
    MySQL8窗口函数应用
    SpringBoot中幕——配置文件properties与yml
    基于知识图谱的职位推荐系统的设计与实现
    远程办公中的IT女性:工作量增加3倍,离职率却下降近50%
    嵌入式Linux入门-Framebuffer应用编程在Linux系统下画个点
    Java开发者的囧境:那些让你苦笑不得的Bug
    Field Play:Runge-Kutta
    弘辽科技:淘宝店流量一直起不来是为什么?流量少怎么办?
  • 原文地址:https://blog.csdn.net/qq_42603590/article/details/139748715
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号