在Unity UI中实现UILineRenderer组件绘制线条
背景介绍
在Unity的UI系统中,绘制线条并不像在3D世界中那样直观(使用Unity自带的LineRender组件在UI中连线并不方便,它在三维中更合适)。没有内置的工具来处理这种需求。如果你希望在UI元素之间绘制连接线(例如在UI上连接不同的图标或控件),需要自己编写逻辑。
目前只适配常规ui情况
为了满足这种需求,我封装了一个名为UILineRenderer的组件。该组件能够处理UI中的线条绘制,并且可以适应UI元素复杂的父子关系,提供线条宽度、颜色设置等功能,非常适合在UI界面中使用。
功能简介
UILineRenderer的主要功能包括:
连接两个UI元素(当然你也可以根据我的思路拓展更多).
支持自定义线条宽度与颜色
能够根据UI元素的坐标变化实时更新线条
通过鼠标位置动态调整线条的终点位置
处理UI元素复杂的父子层级关系
目前仅支持连接两个Ui元素(有一个中间状态就是只添加了一个UI元素,你可以设置鼠标作为第二个临时点,然后在合适的时候设置第二个UI元素)
但是我重写的OnPopulateMesh逻辑实际上是支持连接多个点的,你可以修改这个组件实现你的需求.
先看效果
可以连接两个UI元素

在设置了第一个UI元素的时候,可以设置鼠标位置,从而实现始终连接鼠标(这里截图导致鼠标没了)

源码
using UnityEngine.UI;
using UnityEngine;
using System.Collections.Generic;[RequireComponent(typeof(CanvasRenderer))]//需要该组件才能生效
public class UILineRenderer : Graphic
{private List<Vector2> points = new List<Vector2>(); // 用于存储线条的点[SerializeField] private float lineWidth = 5f; // 线条宽度[SerializeField] private Color lineColor = Color.white; // 默认线条颜色// 每次需要重新绘制UI时调用protected override void OnPopulateMesh(VertexHelper vh){vh.Clear(); // 清空当前顶点数据// 如果没有足够的点,则不绘制任何东西if (points == null || points.Count < 2)return;// 遍历每个点,创建线段for (int i = 0; i < points.Count - 1; i++){Vector2 start = points[i];Vector2 end = points[i + 1];// 计算垂直方向的法线,使线条有宽度Vector2 direction = (end - start).normalized;Vector2 perpendicular = new Vector2(-direction.y, direction.x) * lineWidth / 2f;// 四个顶点(左下、左上、右上、右下)UIVertex vertex = UIVertex.simpleVert;vertex.color = lineColor; // 定义颜色// 左下vertex.position = new Vector3(start.x - perpendicular.x, start.y - perpendicular.y);vh.AddVert(vertex);// 左上vertex.position = new Vector3(start.x + perpendicular.x, start.y + perpendicular.y);vh.AddVert(vertex);// 右上vertex.position = new Vector3(end.x + perpendicular.x, end.y + perpendicular.y);vh.AddVert(vertex);// 右下vertex.position = new Vector3(end.x - perpendicular.x, end.y - perpendicular.y);vh.AddVert(vertex);// 添加两个三角形来组成矩形线条int index = vh.currentVertCount;vh.AddTriangle(index - 4, index - 3, index - 2);vh.AddTriangle(index - 4, index - 2, index - 1);}}/// <summary>/// 设置一个Ui元素/// 为什么要转换坐标?因为UI元素极可能不在同一个父物体下,存在错综复杂的父子关系/// 先获取UiElement世界坐标系转屏幕坐标系再转到此脚本所在的Ui坐标系/// </summary>/// <param name="uiElement"></param>public void AppendUIElement(RectTransform uiElement){Vector2 localPoint;RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, // 当前 UILineRenderer 的 RectTransformRectTransformUtility.WorldToScreenPoint(null, uiElement.position), // UI 元素的世界坐标转换为屏幕坐标null,out localPoint // 输出的局部坐标);// 如果已经有两个点,则移除第二个点,以保持绘制最新线条if (points.Count == 2){points.RemoveAt(1);}// 添加转换后的局部坐标到点列表中points.Add(localPoint);// 标记为需要重新绘制SetVerticesDirty();}/// <summary>/// 设置鼠标位置为第二个点,此时鼠标和第一个UiElement可以构成一条线/// </summary>/// <param name="point"></param>public void SetMouse(){if (points.Count==2){points.RemoveAt(1);}var mousePostion = Input.mousePosition;RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, mousePostion, null, out Vector2 point);points.Add(point);SetVerticesDirty();}/// <summary>/// 设置线的颜色/// </summary>/// <param name="newColor"></param>public void SetLineColor(Color newColor){lineColor = newColor;SetVerticesDirty();}/// <summary>/// 设置线的宽带/// </summary>/// <param name="width"></param>public void SetWidth(float width){lineWidth = width;SetVerticesDirty();}/// <summary>/// 重置组件/// </summary>public void ResetSelf(){points.Clear();lineColor = Color.white;lineWidth = 5f;SetVerticesDirty();}
}
示例
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;public class Test : MonoBehaviour
{public UILineRenderer t;public Image img1;//拖拽public Image img2;private bool keyA = false;// Start is called before the first frame updatevoid Start(){t.AppendUIElement(img1.rectTransform);}// Update is called once per framevoid Update(){if (keyA==false){t.SetMouse();}if (Input.GetKeyDown(KeyCode.A)){keyA = true;t.AppendUIElement(img2.rectTransform);}}}
示例结构图
挂载了UILineRender的组件和其他UI元素一样,所以要放在下面

相关文章:
在Unity UI中实现UILineRenderer组件绘制线条
背景介绍 在Unity的UI系统中,绘制线条并不像在3D世界中那样直观(使用Unity自带的LineRender组件在UI中连线并不方便,它在三维中更合适)。没有内置的工具来处理这种需求。如果你希望在UI元素之间绘制连接线(例如在UI上连接不同的图标或控件)&a…...
C语言中union的用法
在C语言中,union(联合体)是一种特殊的复合数据类型,它允许多个不同的数据成员共享同一块内存空间。与struct(结构体)不同的是,union中的所有成员共用同一个内存地址,因此同时只能存储…...
C++速通LeetCode中等第18题-删除链表的倒数第N个结点(最简单含注释)
绝妙!快慢指针法,快指针先走n步(复杂度O(n),O(1)): /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), next(n…...
鸿蒙 WebView 设置 Header
import { webview } from kit.ArkWebimport { WebHeader } from kit.ArkUI 一共两种方式: 1.把 loadurl的方法写在web组件的生命周期里面 Web({ src:"", controller: this.controller }) .onControllerAttached(()>{ this.controller.loadUrl("…...
电力施工作业安全行为检测图像数据集
电力施工作业安全行为检测图像数据集,图片总共 2300左右,标注为voc(xml)格式,包含高空抛物,未佩戴安全带,高处作业无人监护等。 电力施工作业安全行为检测图像数据集 数据集描述 这是一个专门用于电力施工作业安全行…...
大数据实验2.Hadoop 集群搭建(单机/伪分布式/分布式)
实验二: Hadoop安装和使用 一、实验目的 实现hadoop的环境搭建和安装Hadoop的简单使用; 二、实验平台 操作系统:Linux(建议Ubuntu16.04或者18.04);Hadoop版本:3.1.3;JDK版本&…...
【CSS in Depth 2 精译_036】5.6 Grid 网格布局中与对齐相关的属性 + 5.7本章小结
当前内容所在位置(可进入专栏查看其他译好的章节内容) 第一章 层叠、优先级与继承(已完结) 1.1 层叠1.2 继承1.3 特殊值1.4 简写属性1.5 CSS 渐进式增强技术1.6 本章小结 第二章 相对单位(已完结) 2.1 相对…...
Qt圆角窗口
Qt圆角窗口 问题:自己重写了一个窗口,发现用qss设置圆角了,但是都不生效,不过子窗口圆角都生效了。 无边框移动窗口 bool eventFilter(QObject *watched, QEvent *evt) {static QPoint mousePoint;static bool mousePressed f…...
研究生第一次刷力扣day1
1.给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出和为目标值target 的那两个整数,并返回它们的数组下标 直接采用暴力求解,其他解答案看不懂 大致思想:先用len函数求出数组的长度n,然后一个个遍…...
flink自定义process,使用状态求历史总和(scala)
es idea maven 依赖 <dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-connector-elasticsearch7_2.11</artifactId> <version>1.11.1</version> </dependency> import org.apache.flink.api.common.eve…...
股指期货理论价格计算公式是什么?
股指期货,作为金融衍生品的一种,其价格与现货市场的股指价格紧密相关,但又受到多种因素的影响。了解股指期货理论价格的计算公式,对于投资者进行套利交易、风险管理等具有重要意义。本文将详细解读股指期货理论价格的计算公式&…...
解决R包依赖版本不兼容问题
ERROR: dependency ‘Matrix’ is not available for package ‘irlba’ removing ‘/root/anaconda3/envs/myview/lib/R/library/irlba’ ERROR: dependency ‘Matrix’ is not available for package ‘N2R’ removing ‘/root/anaconda3/envs/myview/lib/R/library/N2R’ ER…...
HarmonyOS开发者基础认证考试试题
文章目录 一、判断题二、单选题三、多选题 因考试只有91分,所以下方答案有部分错误,如果有发现错误,欢迎提出 一、判断题 1. HarmonyOS提供了基础的应用加固安全能力,包括混淆、加密和代码签名能力 正确 2. 用户首选项是关系型数…...
如何使用 React、TypeScript、TailwindCSS 和 Vite 创建 Chrome 插件
创建一个 Chrome 插件是一个有趣的项目,特别是当结合使用强大的工具如 React、TypeScript、TailwindCSS 和 Vite 时 在这篇文章中,我们将逐步引导完成整个过程,了解如何在 2024 年构建自己的 Chrome 插件。无论是经验丰富的开发者还是刚刚起…...
机器学习——Stacking
Stacking: 方法:训练多个模型(可以是强模型),然后将这些模型的预测结果作为新的特征,输入到下一层新的模型(可以是多个)中进行训练,从而得到最终的预测结果。 代表:Stacking本身并没…...
在HTML中添加图片
在HTML中添加图片,你需要使用<img>标签。这个标签用于在网页上嵌入图像。<img>是一个空元素,它只包含属性,并且没有闭合标签。要在<img>标签中指定要显示的图像,你需要使用src(source的缩写…...
R语言机器学习算法实战系列(二) SVM算法(Support Vector Machine)
文章目录 介绍原理应用方向下载数据加载R包导入数据数据预处理数据描述数据切割标准化数据设置参数训练模型预测测试数据评估模型模型准确性混淆矩阵模型评估指标ROC CurvePRC Curve特征的重要性保存模型总结系统信息介绍 支持向量机(Support Vector Machine,简称SVM)是一种…...
gdb调试使用记录
使用 GDB(GNU Debugger)进行问题排查是非常有效的。且可以通过core文件进行排查bug,core文件是程序异常崩溃的时候(段错误,非法指令等),系统自动生成的core文件。用户可以通过core文件配合gdb调试命令,调试…...
ESXi安装【真机和虚拟机】(超详细)
项目简介: ESXi(Elastic Sky X Integrated)是VMware公司开发的一种裸机虚拟化管理程序,允许用户在单一物理服务器上运行多个虚拟机(VM)。它直接安装在服务器硬件上,而不是操作系统之上ÿ…...
基于SpringBoot+Vue的高校门禁管理系统
作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、SSM项目源码 精品专栏:Java精选实战项目源码、Python精…...
day52 ResNet18 CBAM
在深度学习的旅程中,我们不断探索如何提升模型的性能。今天,我将分享我在 ResNet18 模型中插入 CBAM(Convolutional Block Attention Module)模块,并采用分阶段微调策略的实践过程。通过这个过程,我不仅提升…...
MVC 数据库
MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...
【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...
工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配
AI3D视觉的工业赋能者 迁移科技成立于2017年,作为行业领先的3D工业相机及视觉系统供应商,累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成,通过稳定、易用、高回报的AI3D视觉系统,为汽车、新能源、金属制造等行…...
是否存在路径(FIFOBB算法)
题目描述 一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数,分别表示n 和 e 的值(1…...
Fabric V2.5 通用溯源系统——增加图片上传与下载功能
fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...
Linux 内存管理实战精讲:核心原理与面试常考点全解析
Linux 内存管理实战精讲:核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用,还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...
uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)
UniApp 集成腾讯云 IM 富媒体消息全攻略(地理位置/文件) 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型,核心实现方式: 标准消息类型:直接使用 SDK 内置类型(文件、图片等)自…...
Matlab实现任意伪彩色图像可视化显示
Matlab实现任意伪彩色图像可视化显示 1、灰度原始图像2、RGB彩色原始图像 在科研研究中,如何展示好看的实验结果图像非常重要!!! 1、灰度原始图像 灰度图像每个像素点只有一个数值,代表该点的亮度(或…...
跨平台商品数据接口的标准化与规范化发展路径:淘宝京东拼多多的最新实践
在电商行业蓬勃发展的当下,多平台运营已成为众多商家的必然选择。然而,不同电商平台在商品数据接口方面存在差异,导致商家在跨平台运营时面临诸多挑战,如数据对接困难、运营效率低下、用户体验不一致等。跨平台商品数据接口的标准…...
