在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元素

d63c2a97eb7d4e5ca5403bba7af8ad71.png

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

 

4ac6293ab07f480db46aedde2d3da172.png

连线模块小功能: 这是一个连线功能的小插件

这是一个gitee示例

源码

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 的 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 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 update
    void Start()
    {
        t.AppendUIElement(img1.rectTransform);
    }

    // Update is called once per frame
    void Update()
    {
        if (keyA==false)
        {
            t.SetMouse();
        }
       
        if (Input.GetKeyDown(KeyCode.A))
        {
            keyA = true;
            t.AppendUIElement(img2.rectTransform);
        }
    }

   
}

示例结构图

挂载了UILineRender的组件和其他UI元素一样,所以要放在下面

e8bb621fc0a64837a0a1e86c44b75206.png

 

 

 

 

 

### 回答1: UILineRenderer.cs是Unity的一个脚本,用于在Unity绘制2D线段,该脚本通常用于UI元素,例如在屏幕上绘制HUD元素、指示器、边框等。 该脚本使用的是UnityUI系统,因此可以直接添加到UI元素上,例如Image或RawImage。它包含以下属性: - Points: 一个Vector2类型的数组,用于指定线段的顶点。 - LineThickness: 线段的宽度。 - Color: 线段的颜色。 除了这些属性之外,该脚本还包含了一些方法,例如AddPoint和RemovePoint,用于在运行时添加或删除线段的顶点。 使用UILineRenderer.cs,你可以轻松地在Unity创建自定义的线段,例如在UI绘制进度条、血条等。 ### 回答2: UILineRenderer.cs 是 Unity 的一个脚本,用于在屏幕上绘制线段。它是 Unity UI 系统的一部分,可以在 UI 元素上绘制 2D 线条。 使用 UILineRenderer.cs 可以轻松地创建和控制线段的外观和行为。可以根据需要设置线段的起点和终点,在两个点之间绘制一条直线。还可以通过更改线段的宽度、颜色和材质来定制其外观。 UILineRenderer.cs 提供了一些方法和属性来方便地操控线段。其最主要的方法是 SetPoints,可以通过传入一个 Vector2 数组来设置线段的顶点坐标。此外,还有 SetColor、SetWidth 和 SetMaterial 等方法可以用来设置线段的颜色、宽度和材质。 使用 UILineRenderer.cs 绘制线段的过程非常简单。首先,需要在场景创建一个空的 GameObject,并添加 UILineRenderer.cs 脚本组件。然后,在脚本调用相应的方法来设置线段的属性,比如起点、终点、颜色等。最后,将该脚本所在的 GameObject 放置在 UI 元素上,就可以在屏幕上绘制出线段了。 总的来说,UILineRenderer.cs 是 Unity 一个非常有用的工具,可以方便地在 UI 元素上绘制线段,可以用于实现各种需要线条表达的功能和效果,如画笔工具、连接线路等。 ### 回答3: UILineRenderer.cs 是 Unity 引擎的一个脚本,用于在 Unity UI 绘制线段。该脚本利用了 Unity 的 GraphicRaycaster 和 RectTransform 来实现线段的绘制UILineRenderer.cs 提供了一系列属性和方法,用于控制线段的形状、颜色和宽度。通过设置线段的起点和终点坐标,可以在画布上绘制出直线。同时,也可以通过设置控制点来绘制曲线和多段线。 在绘制线段之前,需要将 UILineRenderer.cs 组件添加到 Canvas 对象上。在脚本,需要将起点、终点、控制点等信息传递给 UILineRenderer,并通过调用其 DrawLine() 方法来实现线段的绘制UILineRenderer.cs 利用 Unity 的 GraphicRaycaster 来实现线段的交互功能。我们可以通过代码设置触发事件,如点击或拖拽线段。同时,UILineRenderer.cs 也支持对线段进行颜色、宽度等属性的设置,使其更加美观和有趣。 总的来说,UILineRenderer.cs 是一个在 Unity UI 绘制线段的实用脚本。通过使用该脚本,我们可以方便地在 Unity UI 绘制直线、曲线和多段线,同时也可以实现线段与用户交互的功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值