在Unity UI中实现UILineRenderer组件绘制线条

发布时间:2026/8/27 13:38:01

在Unity UI中实现UILineRenderer组件绘制线条
背景介绍在Unity的UI系统中绘制线条并不像在3D世界中那样直观(使用Unity自带的LineRender组件在UI中连线并不方便,它在三维中更合适)。没有内置的工具来处理这种需求(当然可是使用canvas的第二种模式渲染3维物体到ui然后使用LineRender,这增加了一点复杂性但也不失为一种好办法。如果你只希望在常规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 ListVector2 points new ListVector2(); // 用于存储线条的点 [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 nameuiElement/param public void AppendUIElement(RectTransform uiElement) { Vector2 localPoint; RectTransformUtility.ScreenPointToLocalPointInRectangle( rectTransform, // 当前 UILineRenderer 的 RectTransform RectTransformUtility.WorldToScreenPoint(null, uiElement.position), // UI 元素的世界坐标转换为屏幕坐标 null, out localPoint // 输出的局部坐标 ); // 如果已经有两个点则移除第二个点以保持绘制最新线条 if (points.Count 2) { points.RemoveAt(1); } // 添加转换后的局部坐标到点列表中 points.Add(localPoint); // 标记为需要重新绘制 SetVerticesDirty(); } /// summary /// 设置鼠标位置为第二个点,此时鼠标和第一个UiElement可以构成一条线 /// /summary /// param namepoint/param public void SetMouse() { if (points.Count2) { points.RemoveAt(1); } var mousePostion Input.mousePosition; RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, mousePostion, null, out Vector2 point); points.Add(point); SetVerticesDirty(); } /// summary /// 设置线的颜色 /// /summary /// param namenewColor/param public void SetLineColor(Color newColor) { lineColor newColor; SetVerticesDirty(); } /// summary /// 设置线的宽带 /// /summary /// param namewidth/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 update void Start() { t.AppendUIElement(img1.rectTransform); } // Update is called once per frame void Update() { if (keyAfalse) { t.SetMouse(); } if (Input.GetKeyDown(KeyCode.A)) { keyA true; t.AppendUIElement(img2.rectTransform); } } }示例结构图挂载了UILineRender的组件和其他UI元素一样,所以要放在下面

相关新闻

浏览器本地解密 15 种以上加密音乐:免费开源工具 Unlock Music 完整指南

浏览器本地解密 15 种以上加密音乐:免费开源工具 Unlock Music 完整指南

2026/8/27 13:38:01

浏览器本地解密 15 种以上加密音乐:免费开源工具 Unlock Music 完整指南 【免费下载链接】unlock-music 在浏览器中解锁加密的音乐文件。原仓库: 1. https://github.com/unlock-music/unlock-music ;2. https://git.unlock-music.dev/um/web …

NLP入门到精通必读书籍-《自然语言处理:大模型理论与实践》(预览版)免费pdf分享

NLP入门到精通必读书籍-《自然语言处理:大模型理论与实践》(预览版)免费pdf分享

2026/8/27 13:38:01

前言 《自然语言处理:大模型理论与实践》(预览版)由赵宇教授编写,是一本深入探讨大语言模型世界的专业著作。自然语言处理(Natural Language Processing, NLP)作为计算机科学与人工智能领域的关键技术&…

AMD Ryzen V1000登陆COM Express Type 6:嵌入式载板设计与实测复盘

AMD Ryzen V1000登陆COM Express Type 6:嵌入式载板设计与实测复盘

2026/8/27 13:38:01

这批COM Express Type 6模块拿到手之后,我并没有急着往载板上插。先看了一眼丝印上的SoC型号,然后翻了半天原理图确认Pin-Mux配置,最后才按下电源键。这三年里我经手过的Type 6载板,十块有九块配的是Intel酷睿或者至强嵌入式&…

96Boards SOM规范解读:从交叉编译到载板设计的ARM嵌入式实战指南

96Boards SOM规范解读:从交叉编译到载板设计的ARM嵌入式实战指南

2026/8/27 14:38:04

老读者可能还有印象,96Boards 这几年在开发板圈子里一直挺有存在感,尤其是 Consumer Edition 和 Enterprise Edition 那两条产品线,把 ARM 开发板从“各家各玩各的”往“标准化”方向推了一大步。但嵌入式产品开发真正需要的往往不是一块板子…

MachOExplorer一键发布流水线揭秘:deploy.sh如何搞定签名、公证与Homebrew推送

MachOExplorer一键发布流水线揭秘:deploy.sh如何搞定签名、公证与Homebrew推送

2026/8/27 14:38:04

MachOExplorer一键发布流水线揭秘:deploy.sh如何搞定签名、公证与Homebrew推送 【免费下载链接】machoexplorer 🧱Explore MachO File on macOS and Windows 项目地址: https://gitcode.com/gh_mirrors/ma/machoexplorer MachOExplorer 是一款开源…

MCU离线人脸识别实战:从硬件选型到算法轻量化全解析

MCU离线人脸识别实战:从硬件选型到算法轻量化全解析

2026/8/27 14:38:04

做智能门锁项目的时候,我第一次认真考虑“把离线人脸识别跑在一颗MCU上”这个方向。当时的直觉和大多数人一样:主频只有几百兆赫兹、内部SRAM按KB算、还要外挂SDRAM才能放图像缓冲,这种资源条件怎么跑得动人脸识别?但回过头看&…

Transformer瓶颈与下一代大模型架构:SSM、Mamba与MoE路线解析

Transformer瓶颈与下一代大模型架构:SSM、Mamba与MoE路线解析

2026/8/27 14:38:04

最近大模型圈有两则消息值得放在一起看。一位在 OpenAI 做到较高职级、参与过大模型预训练与扩展性核心工作的人,选择离开;另一位在 Google 深耕多年、长期负责语言模型技术路线的人,也做出同样选择。更关键的是,两人离职后的下一…

5G物联网模块安全落地:从安全启动到TLS双向认证的实践指南

5G物联网模块安全落地:从安全启动到TLS双向认证的实践指南

2026/8/27 14:38:04

1. 从4G到5G,物联网模块的安全门槛到底高在哪先讲一个我今年在项目里遇到的实际场景。客户部署了一批工业数据采集终端,用的还是老的4G Cat.1模块,业务侧跑的是MQTT over TCP,数据明文传输。前期小规模试点没出什么问题&#xff0…

WinDiskWriter:macOS上3步做出Windows启动盘

WinDiskWriter:macOS上3步做出Windows启动盘

2026/8/27 14:28:03

WinDiskWriter:macOS上3步做出Windows启动盘 【免费下载链接】WinDiskWriter 🖥 Windows Bootable USB creator for macOS. 🛠 Patches Windows 11 to bypass TPM and Secure Boot requirements. 👾 UEFI & Legacy Support …

[光学原理与应用-521]:对光的错误理解与纠偏

[光学原理与应用-521]:对光的错误理解与纠偏

2026/8/27 11:10:02

首先光是一种能量的载体和形态,宏观上观察到的光是由无数个微观的光量子组成的,每个光子在产生的瞬间,其在真空的空间中以确定不变的速度沿着一个初始的方向一直向前,在微观层面,每个光量子的运动轨迹是以波函数所展现…

SIP通话转接原理与REFER方法实战解析

SIP通话转接原理与REFER方法实战解析

2026/8/27 7:25:23

1. 通话转接不是“挂断再拨号”,而是SIP会话的动态重定向你有没有遇到过这样的场景:客服坐席A正在和客户通电话,突然需要把这通对话无缝转给专家坐席B,客户完全感知不到中间的断连——既没听到忙音,也没被要求重新拨号…

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

2026/8/26 17:50:58

1. 为什么选择Kolla-ansible来部署单节点OpenStack?如果你正在寻找一种能把OpenStack从“概念”快速变成“可用的实验环境”的方法,那么Kolla-ansible几乎是当前最主流、最省心的选择。我见过太多人卡在手动编译依赖、配置服务、处理版本冲突的泥潭里&am…

Go语言构建企业级AI服务网关:统一管理英伟达等AI接口调用

Go语言构建企业级AI服务网关:统一管理英伟达等AI接口调用

2026/8/27 0:07:12

1. 项目概述:从零构建一个企业级的AI服务网关 最近在帮一个做内容审核的团队做技术架构升级,他们原来的业务里,每天有几十万张图片和短视频需要过审,最初是接了几个开源的AI模型自己部署,但效果和性能一直不太稳定。后…

LeetCode Hot100(51-60)算法精解与面试技巧

LeetCode Hot100(51-60)算法精解与面试技巧

2026/8/27 0:07:12

1. 题目背景与核心价值"hot100(51-60)"这个标题看起来像是某个编程题库或算法练习集中的一组题目编号。在技术社区中,类似命名通常指向LeetCode、牛客网等平台的热门题目集合。作为刷过300题的算法老手,我理解这类题目的核心价值在于&#xff…

CRC校验实战:从模2除法到HJ212协议排错

CRC校验实战:从模2除法到HJ212协议排错

2026/8/27 0:07:12

1. 为什么一个“校验码”能扛住工业现场90%的数据 corruption? 你有没有遇到过这样的场景:嵌入式设备通过RS-485上传温湿度数据,上位机偶尔收到一帧乱码——温度显示成-273℃,湿度跳到999%,但串口波形看起来完全正常&a…

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

2026/8/22 2:02:26

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具,覆盖选题构思、文献整理、内容生成、格式排版等核心场景,真正帮你高效搞定论文难题。 一、全流程王者:一站式搞定论文全链路(一天定稿首…

导师推荐!2026最新AI论文工具测评与实用推荐

导师推荐!2026最新AI论文工具测评与实用推荐

2026/8/26 18:07:30

2026年真正好用的AI论文工具,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

告别游戏崩溃:XCOM 2模组管理器的智能革命

告别游戏崩溃:XCOM 2模组管理器的智能革命

2026/8/26 17:57:52

告别游戏崩溃:XCOM 2模组管理器的智能革命 【免费下载链接】xcom2-launcher The Alternative Mod Launcher (AML) is a replacement for the default game launchers from XCOM 2 and XCOM Chimera Squad. 项目地址: https://gitcode.com/gh_mirrors/xc/xcom2-lau…