在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 的 RectTransformv2,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();}
}