当前位置: 首页 > news >正文

unity UGUI中获取点击位置处的URL链接

需求是,我们在一个text组件中像写网页那样写入链接,然后点击这个链接,就能访问配置的网页啥的。比如:

<a href="hello">链接文本</a></summary>

最终的效果如下:

图中,image区域就是各个链接的点击范围。原理是获取text中,每个字符的位置,然后算出每个链接对应的点击区域,最后返回鼠标点到的那个区域的链接。代码比较简单,就直接写点注释看吧。实现是继承了text组件,当然写成静态方法传入text来计算也可以。

比较一下网上搜到的其他方案,这个方法不用重载mesh,效率应该是比较高的。

#define TEST_CheckClickURL
using System.Collections.Generic;
using System.Text.RegularExpressions;
using UnityEngine;
using UnityEngine.Profiling;
using UnityEngine.UI;public class TestClickURL : Text
{public Button button;public void OnButtonClick(){Debug.Log(CheckClickURL()?.url);}// 定义返回的结果public class CheckClickURLResult{public string url;public string text;public Rect rect;public CheckClickURLResult(string url, string text, Rect rect){this.url = url;this.text = text;this.rect = rect;}}private static Regex hrefRegex =new Regex(@"<a href=([^>\n\s]+)>(.*?)(</a>)",RegexOptions.Singleline);/// <summary> 计算点击到的URL文本内容,返回网址/// 格式如下:<a href="hello">链接文本</a></summary>public CheckClickURLResult CheckClickURL(){Profiler.BeginSample("CheckClickURL");if (hrefRegex == null)hrefRegex = new Regex(@"<a href=([^>\n\s]+)>(.*?)(</a>)", RegexOptions.Singleline);InitDebugGOList();// 将点击位置从屏幕坐标转为本地坐标RectTransformUtility.ScreenPointToLocalPointInRectangle(this.rectTransform, Input.mousePosition,null, out var mouseLocalPosition);//注意使用UI相机// 获取生成的文本数据。// characters 保存了每个字符左上角的位置。// lines 保存了每行开始字符ID,和行高。var generator = cachedTextGenerator;var charList = generator.characters;var lineList = generator.lines;var textStr = text;// 正则表达式查找链接文本var matchs = hrefRegex.Matches(textStr);foreach (Match match in matchs){var urlGroup = match.Groups[1];var textGroup = match.Groups[0];var textStartIndex = textGroup.Index;var textEndIndex = textGroup.Index + textGroup.Length;// 我们的字符可能是换行的,所以要按行分割。// 倒着遍历就很容易获取每行开始和结束位置。var lineEndIndex = charList.Count - 1;for (int i = lineList.Count - 1; i >= 0; i--){var lineStartIndex = lineList[i].startCharIdx;// 处理换行后的截取var realStart = Mathf.Max(lineStartIndex, textStartIndex);var realEnd = Mathf.Min(lineEndIndex, textEndIndex);// 本行没有链接内容的情况if (realStart > realEnd) continue;// 问题简化成单行的点击检查,提个函数继续处理。var result = CheckLine(realStart, realEnd, lineList[i].height, mouseLocalPosition, out var rect);if (result) return new CheckClickURLResult(urlGroup.Value, textGroup.Value, rect);//Debug.Log($"{start}/{end}");lineEndIndex = lineStartIndex - 1;}}Profiler.EndSample();return null;}public bool CheckLine(int start, int end, float lineHeight, Vector2 mouseLocalPosition, out Rect rect){// 获取生成的文本数据。var charList = cachedTextGenerator.characters;var startPoint = charList[start].cursorPos;var endPoint = charList[end].cursorPos;// 直接计算出本行中链接可点击区域。var x = startPoint.x;var y = startPoint.y - lineHeight;var width = endPoint.x - startPoint.x;var height = lineHeight;rect = new Rect(x, y, width, height);var result = rect.Contains(mouseLocalPosition);CreateDebugImage(rect, result);return result;}#if TEST_CheckClickURL// 测试用。生成空image展示出点击判定范围。public static List<GameObject> debugGOList;public void CreateDebugImage(Rect rect, bool contains){Debug.Log($"rect={rect}");var go = new GameObject("DebugImage",typeof(RectTransform), typeof(Image));debugGOList.Add(go);var rtf = go.GetComponent<RectTransform>();rtf.SetParent(transform);rtf.pivot = Vector2.zero;rtf.anchorMin = Vector2.one / 2;rtf.anchorMax = Vector2.one / 2;rtf.sizeDelta = rect.size;rtf.localScale = Vector3.one;rtf.rotation = Quaternion.identity;rtf.anchoredPosition = rect.position - rectTransform.rect.center;// 点击到的那个范围展示为红色。if (contains)go.GetComponent<Image>().color = Color.red;}public void InitDebugGOList(){if (debugGOList == null)debugGOList = new List<GameObject>();debugGOList.ForEach(p => Destroy(p));}
#elsepublic void CreateDebugImage(Rect rect, bool contains) { }public void InitDebugGOList() { }
#endif
}

相关文章:

unity UGUI中获取点击位置处的URL链接

需求是&#xff0c;我们在一个text组件中像写网页那样写入链接&#xff0c;然后点击这个链接&#xff0c;就能访问配置的网页啥的。比如&#xff1a; <a href"hello">链接文本</a></summary> 最终的效果如下&#xff1a; 图中&#xff0c;image区…...

【Arduino库之:FastLED库】

第一&#xff1a;基础 led [ 0 ] CRGB::Red; //为第一个灯珠设置红色 FastLED.show(); //这个作用才会显示 示例程序&#xff1a; #include <FastLED.h> #define NUM_LEDS 8 #define DATA_PIN 7 #define CLOCK_PIN 13 CRGB leds[NUM_LEDS]; CRGB myGRBcolor(0…...

两道面试题秒杀你的C++基础!

大家好&#xff0c;我是光城&#xff0c;今天发两个非常重要的面试题&#xff0c;可以留言区说出你的答案&#xff0c;这两个题目都比较重要&#xff0c;看你能答对不&#xff1f; 1.C中初始化变量有几种方式&#xff0c;各自有什么区别&#xff1f; 或者说Initialization分为哪…...

回归预测 | MATLAB实现SMA+WOA+BOA-LSSVM基于黏菌算法+鲸鱼算法+蝴蝶算法优化LSSVM回归预测

回归预测 | MATLAB实现SMAWOABOA-LSSVM基于黏菌算法鲸鱼算法蝴蝶算法优化LSSVM回归预测 目录 回归预测 | MATLAB实现SMAWOABOA-LSSVM基于黏菌算法鲸鱼算法蝴蝶算法优化LSSVM回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 MATLAB实现SMAWOABOA-LSSVM基于黏菌算法…...

柔性数组(Flexible Array Members)在C语言中的应用

什么是柔性数组&#xff1f; 在C语言中&#xff0c;柔性数组&#xff08;Flexible Array Members&#xff0c;FAMs&#xff09;是C99标凈引入的一种便捷的数据结构&#xff0c;用于声明具有可变大小数组的结构体。柔性数组通常用于当结构体的大小在编译时不确定&#xff0c;但…...

华为手环配置技巧

前言 华为手环作为生活健康辅助设备发挥不可忽视的作用&#xff0c;但每次更换手环后需要重新配置。华为手环不仅有健康监测、消息通知、天气推送、离线支付、公交卡、运动锻炼、等功能&#xff0c;还有倒计时、计时器、手电筒、闹钟、等小工具。下文介绍如何进行配置。 配置…...

2023全球数字贸易大赛--什么是 DID 身份,中青校园APP,全球碳交易=树根格致,多元空间=购物时代的web3.0,超喵Overview

目录 什么是 DID 身份,为什么需要 DID 1. 中心化身份的问题 2. 为什么 DID 一定会出现...

有序表常见题型

给定一个数组arr和两个整数a和b求arr中有多少个子数组累加和在a到b这个范围上返回达标的子数组数量 如【3&#xff0c;6&#xff0c;1&#xff0c;9&#xff0c;2】达标的子数组通过暴力求解的方式时间复杂度为O&#xff08;N的三次方&#xff09;【找每个子数组占用O&#xf…...

【开源】基于JAVA语言的桃花峪滑雪场租赁系统

项目编号&#xff1a; S 036 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S036&#xff0c;文末获取源码。} 项目编号&#xff1a;S036&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 游客服务2.2 雪场管理 三、数据库设…...

【开源】基于Vue.js的图书管理系统

文末获取源码&#xff0c;项目编号&#xff1a; S 066 。 \color{red}{文末获取源码&#xff0c;项目编号&#xff1a;S066。} 文末获取源码&#xff0c;项目编号&#xff1a;S066。 目录 一、 系统介绍二、 功能模块2.1 登录注册模块2.1 图书馆模块2.2 图书类型模块2.3 图书模…...

python跑ncnn(验证模型是否转换成功)

为了转ncnn模型是否成功&#xff0c;用python验证一下先 pip install ncnn分割模型的验证代码 import ncnn import cv2 import numpy as np# 创建ncnn的网络对象 net ncnn.Net()# 加载ONNX模型 net.load_param(E:\\Android_Projects\\ncnn-android-deeplabv3plus-main\\app\…...

FL Studio 21.2.1.3859中文破解激活版2024免费下载安装图文教程

FL Studio 21.2.1.3859中文破解激活版是我见过更新迭代最快的宿主软件&#xff0c;没有之一。FL Studio12、FL Studio20、FL Studio21等等。有时甚至我刚刚下载好了最新版本&#xff0c;熟悉了新版本一些好用的操作&#xff0c;Fl Studio就又推出了更新的版本&#xff0c;而且F…...

人工智能发展史

人工智能&#xff08;AI&#xff09;的发展史是一段跨越数十年的旅程&#xff0c;涵盖了从早期理论探索到现代技术革新的广泛内容。人工智能的发展历程展示了从最初的概念探索到现代技术突破的演变。尽管经历了多次起伏&#xff0c;但AI领域持续进步&#xff0c;不断拓展其应用…...

【面试经典 150 | 二分查找】搜索插入位置

文章目录 写在前面Tag题目来源题目解读解题思路方法一&#xff1a;二分查找闭区间左闭右开区间开区间总结 知识总结写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c…...

DAPP开发【06】nodejs安装与npm路径更换

windows系统在执行用户命令时顺序 windows系统在执行用户命令时&#xff0c;若用户未给出文件的绝对路径&#xff0c; 则 &#xff08;1&#xff09;首先在当前目录下寻找相应的可执行文件、批处理文件等&#xff1b; &#xff08;2&#xff09;若找不到&#xff0c;再依次在系…...

数据结构奇妙旅程之顺序表和链表

꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN …...

vitepress的使用

创建项目并启动项目 // 1.创建项目,直接在空项目下安装vitepress(npm/yarn等都可以,这个可以看官网,官网给了好几种安装方式) yarn add -D vitepress // 2.初始化配置项目(npm/官网也给了多种包管理工具的安装方式) npx vitepress init // 初始化命令执行完会遇到以下几个问题…...

Discuz论坛自动采集发布软件

随着网络时代的不断发展&#xff0c;Discuz论坛作为一个具有广泛用户基础的开源论坛系统&#xff0c;其采集全网文章的技术也日益受到关注。在这篇文章中&#xff0c;我们将专心分享通过输入关键词实现Discuz论坛的全网文章采集&#xff0c;同时探讨采集过程中伪原创的发布方法…...

B树在数据库的应用

B树&#xff08;B-tree&#xff09;是一种自平衡的树状数据结构&#xff0c;广泛应用于数据库和文件系统等领域&#xff0c;其设计的目标是提供一种高效的插入、删除和查找操作。B树的设计是为了在磁盘等存储介质上存储和操作大量的数据。 主要特点包括&#xff1a; 平衡性&a…...

Android 源码编译

一&#xff0c;虚拟机安装 ​ 1.1 进入https://cn.ubuntu.com/download中文官网下载iso镜像 1.2 这里我们下载Ubuntu 18.04 LTS 1.3虚拟VM机安装ubuntu系统&#xff0c;注意编译源码需要至少16G运行内存和400G磁盘空间&#xff0c;尽量设大点 二 配置编译环境 2.1 下载andr…...

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

vscode里如何用git

打开vs终端执行如下&#xff1a; 1 初始化 Git 仓库&#xff08;如果尚未初始化&#xff09; git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...

C++ 基础特性深度解析

目录 引言 一、命名空间&#xff08;namespace&#xff09; C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用&#xff08;reference&#xff09;​ C 中的引用​ 与 C 语言的对比​ 四、inline&#xff08;内联函数…...

反射获取方法和属性

Java反射获取方法 在Java中&#xff0c;反射&#xff08;Reflection&#xff09;是一种强大的机制&#xff0c;允许程序在运行时访问和操作类的内部属性和方法。通过反射&#xff0c;可以动态地创建对象、调用方法、改变属性值&#xff0c;这在很多Java框架中如Spring和Hiberna…...

Axios请求超时重发机制

Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式&#xff1a; 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

12.找到字符串中所有字母异位词

&#x1f9e0; 题目解析 题目描述&#xff1a; 给定两个字符串 s 和 p&#xff0c;找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义&#xff1a; 若两个字符串包含的字符种类和出现次数完全相同&#xff0c;顺序无所谓&#xff0c;则互为…...

大学生职业发展与就业创业指导教学评价

这里是引用 作为软工2203/2204班的学生&#xff0c;我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要&#xff0c;而您认真负责的教学态度&#xff0c;让课程的每一部分都充满了实用价值。 尤其让我…...

优选算法第十二讲:队列 + 宽搜 优先级队列

优选算法第十二讲&#xff1a;队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill

视觉语言模型&#xff08;Vision-Language Models, VLMs&#xff09;&#xff0c;为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展&#xff0c;机器人仍难以胜任复杂的长时程任务&#xff08;如家具装配&#xff09;&#xff0c;主要受限于人…...