Unity中在UI上画线

news2025/1/24 1:30:52

在UI中画一条曲线

我封装了一个组件,可以实现基本的画线需求.

效果

按住鼠标左键随手一画.

用起来也很简单,将组件挂到空物体上就行了,红色的背景是Panel.

你可以将该组件理解为一个Image,只不过形状更灵活一些罢了,所以它要放在下面的层级(不然可能会被挡住).

代码

可以调整一些基本的属性,如线的颜色和粗细.

using System;
using UnityEngine.UI;
using UnityEngine;
using System.Collections.Generic;
using Unity.VisualScripting;

[RequireComponent(typeof(CanvasRenderer))] //需要该组件才能生效
public class UILineRenderer : Graphic
{
    private readonly List<Vector2> points = new List<Vector2>(); // 用于存储线条的点

    [SerializeField] private float lineWidth = 5f; // 线条宽度
    [SerializeField] private Color lineColor = Color.white; // 默认线条颜色

    //----用来测试,你应当使用自己的办法调用DrawLine方法,后续删除这部分-----
    private List<Vector2> points1 = new List<Vector2>(); // 用于存储线条的点

    private void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            points1.Clear();
        }
        else if (Input.GetMouseButton(0))
        {
            points1.Add(Input.mousePosition);
            DrawLine(points1);
        }
        else if (Input.GetMouseButtonUp(0))
        {
            foreach (var VARIABLE in points1)
            {
                Debug.Log(VARIABLE);
            }
        }
    }
    //--------------------------------------------------------

    // 每次需要重新绘制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);
        }
    }


    public void DrawLine(List<Vector2> pointArray)
    {
        if (pointArray == null || pointArray.Count < 2) return;

        List<Vector2> newPoints = new List<Vector2>();
        foreach (Vector2 v2 in pointArray)
        {
            Vector2 localPoint;
            RectTransformUtility.ScreenPointToLocalPointInRectangle(
                rectTransform, // 当前 UILineRenderer 的 RectTransform
                v2,
                null,
                out localPoint // 输出的局部坐标
            );
            newPoints.Add(localPoint);
        }

        this.points.Clear();
        this.points.AddRange(newPoints);

        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();
    }
}

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2281157.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Cloud Foundry,K8S,Mesos Marathon弹性扩缩容特性对比

一、Cloud Foundry 使用Scaling an Application Using App Autoscaler插件&#xff0c;基于资源使用情况触发简单扩缩容 CPU、内存、Http带宽、延时等 监控这些资源的使用情况决定扩缩容策略&#xff1a;实例是增加还是减少 Instance Limits 限制实例数量范围&#xff0c;定义…

Qt —— 控件属性

一、概述 控件有很多属性&#xff0c;我们学习和整理常见和常用的几个属性&#xff0c;由于所有的控件基本都是继承Widget类的&#xff0c;所以前面会先拿Widget类和常见的控件进行示范。 Qt Designer左侧一长条就是Qt给我们内置好的控件&#xff1a; 二、enabled 状态属性 …

vue+高德API搭建前端Echarts图表页面

利用vue搭建Echarts图表页面&#xff0c;在搭建Echarts图表中&#xff0c;如果搭建地理地形图需要准备一些额外的文件&#xff0c;地理json文件和js文件&#xff0c;js文件目前在网上只能找省一级的&#xff0c;json文件有对应的省市县&#xff0c;js文件和json文件对应的也是不…

Gartner发布2025年网络治理、风险与合规战略路线图

新型网络风险和合规义务&#xff0c;日益成为网络治理、风险与合规实践面临的问题。安全和风险管理领导者可以参考本文&#xff0c;实现从被动、专注于合规的方法到主动、进一步自动化方法的转型。 主要发现 不断变化的监管环境和不断扩大的攻击面&#xff0c;使企业机构难以实…

Redis 集群模式入门

Redis 集群模式入门 一、简介 Redis 有三种集群模式&#xff1a;主从模式、Sentinel 哨兵模式、cluster 分片模式 主从复制&#xff08;Master-Slave Replication&#xff09;: 在这种模式下&#xff0c;数据可以从一个 Redis 实例&#xff08;主节点 Master&#xff09;复…

查看电脑或笔记本CPU的核心数方法及CPU详细信息

一、通过任务管理器查看 1.打开任务管理器 可以按下“Ctrl Shift Esc”组合键&#xff0c;或者按下“Ctrl Alt Delete”组合键后选择“任务管理器”来打开。 2.查看CPU信息 在任务管理器界面中&#xff0c;点击“性能”标签页&#xff0c;找到CPU使用记录区域&#xff0c…

光学遥感显著性目标检测2023-2024论文学习

GRSL 2023&#xff1a; Attention-Aware Three-Branch Network for Salient Object Detection in Remote Sensing Images 基于encoder-decoder框架&#xff0c;提出了一系列缝合模块&#xff0c;GCA&#xff0c;FDUC&#xff0c;MSDC&#xff0c;RA。 GRSL 2023&#xff1a;OR…

Kubernetes 集群中安装和配置 Kubernetes Dashboard

前言 上篇成功部署Kubernetes集群后&#xff0c;为了方便管理和监控集群资源&#xff0c;安装Kubernetes Dashboard显得尤为重要。Kubernetes Dashboard 是一个通用的、基于 Web 的 UI&#xff0c;旨在让用户轻松地部署容器化应用到 Kubernetes 集群&#xff0c;并对这些应用进…

2025西湖论剑-babytrace

前言 就做了下题目&#xff0c;pwn1/3 都是签到&#xff0c;pwn2 后面绕 ptrace 有点意思&#xff0c;简单记录一下 漏洞分析 子进程中的读/写功能没有检查负数的情况&#xff0c;存在越界读写&#xff1a; void __fastcall get_value(__int64 *int64_arr) {__int64 ll; //…

HarmonyOS Next 应用UI生成工具介绍

背景 HarmonyOS Next适配开发过程中难买难要参考之前逻辑&#xff0c;但是可能时间较长文档不全&#xff0c;只能参考Android或iOS代码&#xff0c;有些逻辑较重的场景还可以通过AI工具将Android 的Java代码逻辑转成TS完成部分复用。对于一些UI场景只能手动去写&#xff0c;虽…

计算机网络 (56)交互式音频/视频

一、定义与特点 定义&#xff1a;交互式音频/视频是指用户使用互联网和其他人进行实时交互式通信的技术&#xff0c;包括语音、视频图像等多媒体实时通信。 特点&#xff1a; 实时性&#xff1a;音频和视频数据是实时传输和播放的&#xff0c;用户之间可以进行即时的交流。交互…

【深度学习】Java DL4J 2024年度技术总结

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…

考研408笔记之数据结构(三)——串

数据结构&#xff08;三&#xff09;——串 1. 串的定义和基本操作 本节内容很少&#xff0c;重点是串的模式匹配&#xff0c;所以对于串的定义和基本操作&#xff0c;我就简单提一些易错点。另外&#xff0c;串也是一种特殊的线性表&#xff0c;只不过线性表是可以存储任何东…

Spring Data JPA使用基础教程

文章目录 Spring Data JPA使用基础教程一、引言二、环境搭建1、添加依赖2、配置数据库 三、核心组件1、实体类2、Repository 接口 四、使用示例1、基本操作1.1、保存数据1.2、查询数据1.3、更新数据1.4、删除数据 2、自定义查询 五、最佳实践1. **合理使用懒加载与急加载**2. *…

到华为考场考HCIE的注意事项和考试流程

大家好&#xff0c;我是张同学&#xff0c;来自成都职业技术学院2021级计算机网络专业。最近成功通过了 Datacom HCIE 考试&#xff0c;在这里和大家分享一下我的经验。 考证契机 在母校的培养下&#xff0c;我接触到ICT这个行业&#xff0c;打好了基础&#xff0c;开始了成…

STM32 ST7735 128*160

ST7735 接口和 STM32 SPI 引脚连接 ST7735 引脚功能描述STM32 引脚连接&#xff08;示例&#xff0c;使用 SPI1&#xff09;SCLSPI 时钟信号 (SCK)PA0(SPI1_SCK)SDASPI 数据信号 (MOSI)PA1 (SPI1_MOSI)RST复位信号 (Reset)PA2(GPIO 手动控制)DC数据/命令选择 (D/C)PA3 (GPIO 手…

大华相机DH-IPC-HFW3237M支持的ONVIF协议

使用libONVIF C库。 先发现相机。 配置 lib目录 包含 编译提示缺的文件&#xff0c;到libonvif里面拷贝过来。 改UDP端口 代码 使用msvc 2022的向导生成空项目&#xff0c;从项目的main示例拷贝过来。 CameraOnvif.h #pragma once#include <QObject> #include &l…

JavaWeb过滤器和监听器实现网页计数功能

过滤器用于在请求到达Servlet之前或响应返回给客户端之前对请求或响应进行预处理或后处理操作&#xff0c;监听器用于监听Web应用中的事件。 实现网页计数功能。要完成两项计数&#xff1a; 第一&#xff0c;本网页历史访问人数&#xff1b; 第二&#xff0c;本站当前在线用户…

AIGC视频生成明星——Emu Video模型

大家好&#xff0c;这里是好评笔记&#xff0c;公主号&#xff1a;Goodnote&#xff0c;专栏文章私信限时Free。本文详细介绍Meta的视频生成模型Emu Video&#xff0c;作为Meta发布的第二款视频生成模型&#xff0c;在视频生成领域发挥关键作用。 &#x1f33a;优质专栏回顾&am…

Genetic Prompt Search via Exploiting Language Model Probabilities

题目 利用语言模型概率的遗传提示搜索 论文地址&#xff1a;https://www.ijcai.org/proceedings/2023/0588.pdf 项目地址&#xff1a;https://github.com/zjjhit/gap3 摘要 针对大规模预训练语言模型(PLMs)的即时调优已经显示出显著的潜力&#xff0c;尤其是在诸如fewshot学习…