当前位置: 首页 > 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面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下&#xff0c;越来越多的求职者将目光投向了日本及中日双语岗位。但是&#xff0c;一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧&#xff1f;面对生疏的日语交流环境&#xff0c;即便提前恶补了…...

智慧医疗能源事业线深度画像分析(上)

引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...

React Native 开发环境搭建(全平台详解)

React Native 开发环境搭建&#xff08;全平台详解&#xff09; 在开始使用 React Native 开发移动应用之前&#xff0c;正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南&#xff0c;涵盖 macOS 和 Windows 平台的配置步骤&#xff0c;如何在 Android 和 iOS…...

基于Docker Compose部署Java微服务项目

一. 创建根项目 根项目&#xff08;父项目&#xff09;主要用于依赖管理 一些需要注意的点&#xff1a; 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件&#xff0c;否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

是否存在路径(FIFOBB算法)

题目描述 一个具有 n 个顶点e条边的无向图&#xff0c;该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序&#xff0c;确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数&#xff0c;分别表示n 和 e 的值&#xff08;1…...

代理篇12|深入理解 Vite中的Proxy接口代理配置

在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

iview框架主题色的应用

1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题&#xff0c;无需引入&#xff0c;直接可…...

如何应对敏捷转型中的团队阻力

应对敏捷转型中的团队阻力需要明确沟通敏捷转型目的、提升团队参与感、提供充分的培训与支持、逐步推进敏捷实践、建立清晰的奖励和反馈机制。其中&#xff0c;明确沟通敏捷转型目的尤为关键&#xff0c;团队成员只有清晰理解转型背后的原因和利益&#xff0c;才能降低对变化的…...

实战设计模式之模板方法模式

概述 模板方法模式定义了一个操作中的算法骨架&#xff0c;并将某些步骤延迟到子类中实现。模板方法使得子类可以在不改变算法结构的前提下&#xff0c;重新定义算法中的某些步骤。简单来说&#xff0c;就是在一个方法中定义了要执行的步骤顺序或算法框架&#xff0c;但允许子类…...

Vue3 PC端 UI组件库我更推荐Naive UI

一、Vue3生态现状与UI库选择的重要性 随着Vue3的稳定发布和Composition API的广泛采用&#xff0c;前端开发者面临着UI组件库的重新选择。一个好的UI库不仅能提升开发效率&#xff0c;还能确保项目的长期可维护性。本文将对比三大主流Vue3 UI库&#xff08;Naive UI、Element …...