Archived
给组件改名了
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XericLibrary.Runtime.UIGraph
|
||||
{
|
||||
/// <summary>
|
||||
/// UI上线条绘制组件
|
||||
/// 支持设置线条厚度、居中显示,并为线段之间添加斜角边缘
|
||||
/// 继承自 MaskableGraphic,可与 UI 遮罩系统配合使用
|
||||
/// </summary>
|
||||
[AddComponentMenu("Xeric Library/UI/UILineRenderer", 15)]
|
||||
public class UILineRenderer : XericRendererComponent
|
||||
{
|
||||
// todo 根据优弧劣弧绘制线段,这么说可能不太准确,但我需要在90度以内绘制漂亮的转角,大于90度则用中心圆代替
|
||||
#region 字段属性
|
||||
|
||||
/// <summary>
|
||||
/// 线条的顶点数组,至少需要 2 个点才能绘制线条
|
||||
/// 点的坐标基于本地空间,中心点由 center 属性控制
|
||||
/// </summary>
|
||||
public List<Vector2> points = new List<Vector2>();
|
||||
private Vector2[] _points;
|
||||
|
||||
public float thickness = 10f;
|
||||
public bool center = true;
|
||||
public bool cycleLoop = false;
|
||||
|
||||
/// <summary>
|
||||
/// 是否启用倒角功能
|
||||
/// </summary>
|
||||
public bool useChamfer = false;
|
||||
|
||||
/// <summary>
|
||||
/// 倒角细分数量,控制圆弧的平滑度
|
||||
/// </summary>
|
||||
public int chamferSegments = 4;
|
||||
|
||||
/// <summary>
|
||||
/// 内圆弧半径,当大于0时启用内圆弧
|
||||
/// </summary>
|
||||
public float innerRadius = 0f;
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 添加顶点
|
||||
/// </summary>
|
||||
/// <param name="point"></param>
|
||||
/// <param name="mergingRadius">合并弧度,指定一个弧度,在添加顶点时,自动合并之前的顶点为直线</param>
|
||||
public void AddPoint(Vector2 point, float mergingRadius = -1)
|
||||
{
|
||||
if (mergingRadius > 0 && points.Count >= 2)
|
||||
{
|
||||
var a = points[^1];
|
||||
var b = Vector3.Dot((a - points[^2]).normalized, (a - point).normalized);
|
||||
|
||||
if (b < mergingRadius)
|
||||
points[^1] = point;
|
||||
return;
|
||||
}
|
||||
points.Add(point);
|
||||
Refresh();
|
||||
}
|
||||
|
||||
public void RemovePoint(int index)
|
||||
{
|
||||
points.RemoveAt(index);
|
||||
Refresh();
|
||||
}
|
||||
|
||||
public void CleanPoint(Vector2 point)
|
||||
{
|
||||
points.Clear();
|
||||
Refresh();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成线条网格
|
||||
/// </summary>
|
||||
/// <param name="vh">用于构建网格的 VertexHelper 对象</param>
|
||||
protected override void OnPopulateMesh(VertexHelper vh)
|
||||
{
|
||||
// 清空现有的网格数据
|
||||
vh.Clear();
|
||||
|
||||
var offset = XericRendererUtils.SwitchCenterOffset(center, rectTransform.sizeDelta);
|
||||
_points = points.ToArray();
|
||||
|
||||
if (useChamfer)
|
||||
{
|
||||
vh.PopulateLineByPointsArray_CFAL(_points, thickness, cycleLoop, color, offset, chamferSegments, innerRadius);
|
||||
}
|
||||
else
|
||||
{
|
||||
vh.PopulateLineByPointsArray_DSL5(_points, thickness, cycleLoop, color, offset);
|
||||
}
|
||||
|
||||
|
||||
|
||||
return;
|
||||
// 至少需要 2 个点才能绘制线条
|
||||
if (_points.Length < 2)
|
||||
return;
|
||||
|
||||
// 计算线路总长度
|
||||
float totalLength = _points.CalculateTotalLength();
|
||||
float currentLength = 0f;
|
||||
|
||||
// 遍历所有点,创建线段并添加到网格中
|
||||
for (int i = 0; i < _points.Length-1; i++)
|
||||
{
|
||||
// 使用静态工具方法创建当前点与下一个点之间的线段
|
||||
// 传递当前累积长度和总长度用于UV坐标计算
|
||||
vh.CreateLineSegment_CFAL(_points[i], _points[i+1],
|
||||
i > 0 ? Mathf.Acos(Vector2.Dot((_points[i] - _points[i -1]).normalized, (_points[i + 1] - _points[i]).normalized)) * Mathf.Rad2Deg : 0,
|
||||
i < _points.Length-2 ? Mathf.Acos(Vector2.Dot((_points[i] - _points[i + 1]).normalized, (_points[i + 1] - _points[i +2]).normalized)) * Mathf.Rad2Deg : 0,
|
||||
thickness, center, rectTransform.sizeDelta, color, currentLength, totalLength);
|
||||
|
||||
// 更新累积长度
|
||||
currentLength += Vector2.Distance(_points[i], _points[i+1]);
|
||||
|
||||
// 计算当前线段的顶点索引(每个线段包含 5 个顶点)
|
||||
int index = i * 5;
|
||||
|
||||
// 添加线段的两个三角形(构成矩形线段)
|
||||
vh.AddTriangle(index, index+1, index+3);
|
||||
vh.AddTriangle(index+3, index+2, index);
|
||||
|
||||
// 为线段之间添加斜角边缘
|
||||
// 使用上一个线段的终点和当前线段的起点创建过渡三角形
|
||||
if (i != 0)
|
||||
{
|
||||
vh.AddTriangle(index, index-1, index-3);
|
||||
vh.AddTriangle(index+1, index-1, index-2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user