From 45944e45394a071cef35476dec89cc91347619f0 Mon Sep 17 00:00:00 2001
From: lrc <571244399@qq.com>
Date: Mon, 6 Jul 2026 17:04:54 +0800
Subject: [PATCH] =?UTF-8?q?=E8=A1=A5=E5=85=85=E6=B3=A8=E9=87=8A=E5=8F=8A?=
=?UTF-8?q?=E6=9B=B4=E5=A4=9A=E7=94=A8=E6=B3=95=E3=80=82?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
Runtime/Core/XericRendererUtils.cs | 361 +++++++++++++++-------
Runtime/Pattern/UIAnyPatternRenderer.cs | 17 +
Runtime/Pattern/UILineRenderer.cs | 56 +++-
Runtime/Pattern/UIPatternRenderer.cs | 17 +
Runtime/Pattern/XericRendererComponent.cs | 89 +++++-
5 files changed, 406 insertions(+), 134 deletions(-)
diff --git a/Runtime/Core/XericRendererUtils.cs b/Runtime/Core/XericRendererUtils.cs
index a615122..f28ecac 100644
--- a/Runtime/Core/XericRendererUtils.cs
+++ b/Runtime/Core/XericRendererUtils.cs
@@ -13,7 +13,7 @@ namespace XericLibrary.Runtime.UIGraph
internal static class XericRendererUtils
{
#region 数学计算
-
+
///
/// 计算线路的总长度
///
@@ -54,7 +54,8 @@ namespace XericLibrary.Runtime.UIGraph
/// 是否要居中显示
/// 整个绘制矩形范围的尺寸
///
- public static Vector2 SwitchCenterOffset(bool center, Vector2 rectSize) => center ? Vector2.zero : -(rectSize / 2);
+ public static Vector2 SwitchCenterOffset(bool center, Vector2 rectSize) =>
+ center ? Vector2.zero : -(rectSize / 2);
///
/// 获取两个点之间的法线,副法线
@@ -65,19 +66,21 @@ namespace XericLibrary.Runtime.UIGraph
/// 两点间距离
/// 起点到终点的法线
/// 垂直与起点到终点的法线(法线左转90)
+ /// 反转矢量
///
- private static bool GetNormalizedVector(Vector2 startPoint, Vector2 endPoint,
- out Vector2 vector, out float distance, out Vector2 normal, out Vector2 subTangent)
+ private static bool GetNormalizedVector(Vector2 startPoint, Vector2 endPoint,
+ out Vector2 vector, out float distance, out Vector2 normal, out Vector2 subTangent,
+ bool reverseVector = false)
{
- vector = endPoint - startPoint;
+ vector = reverseVector ? startPoint - endPoint : endPoint - startPoint;
distance = vector.magnitude;
normal = Vector2.zero;
subTangent = Vector2.zero;
-
+
// 距离过小时不绘制
if (distance <= float.Epsilon)
return false;
-
+
// 线段的法线和副法线
normal = vector / distance;
subTangent = Vector2.Perpendicular(normal);
@@ -96,19 +99,20 @@ namespace XericLibrary.Runtime.UIGraph
/// 总线路的长度
/// 起点处的uv y
/// 终点处的uv y
- private static void GetCurrentLengthUVY(float startLength, float currentLength, float totalLength, out float startUVY, out float endUVY)
+ private static void GetCurrentLengthUVY(float startLength, float currentLength, float totalLength,
+ out float startUVY, out float endUVY)
{
startUVY = totalLength > 0 ? startLength / totalLength : 0f;
endUVY = totalLength > 0 ? (startLength + currentLength) / totalLength : 0f;
}
-
+
#endregion
#region 简易线路绘制
-
+
// 在点与点之间绘制给定宽度(thickness)的方片,转角处用两个三角形链接
// 这样会造成一根线会出现5个顶点,所以叫做 DSL5 (直接简单的5点直线 directly simple line 5)
-
+
///
/// 创建线段的顶点数据
/// 每个线段由 5 个顶点组成:
@@ -124,8 +128,10 @@ namespace XericLibrary.Runtime.UIGraph
/// 线条的颜色
/// 当前线段起点在线路中的累积长度
/// 线路的总长度
- public static List GetSingleLineSegmentVerts_DSL5(List vertices, Vector2 startPoint, Vector2 endPoint,
- float thickness, Color color, float startLength, out float distance, float totalLength, Vector3 offset)
+ public static List GetSingleLineSegmentVerts_DSL5(List vertices, Vector2 startPoint,
+ Vector2 endPoint,
+ float thickness, Color color, Vector2 normal, Vector2 subTangent, float startUVY, float endUVY,
+ Vector3 offset)
{
if (vertices == null)
throw new Exception("没有指定线段片段顶点容器列表");
@@ -134,35 +140,29 @@ namespace XericLibrary.Runtime.UIGraph
UIVertex vertex = UIVertex.simpleVert;
vertex.color = color;
- if (!GetNormalizedVector(startPoint, endPoint,
- out var vector, out distance, out var normal, out var subTangent))
- return vertices;
-
// 线段单侧宽度
var width = thickness / 2;
-
- GetCurrentLengthUVY(startLength, distance, totalLength, out var startUVY, out var endUVY);
-
- vertex.position = (startPoint +
- subTangent * width);
+
+ vertex.position = (startPoint +
+ subTangent * width);
vertex.position += offset;
vertex.uv0 = new Vector2(0f, startUVY); // 左侧顶点的UV
vertices.Add(vertex);
-
- vertex.position = (startPoint +
- subTangent * -width);
+
+ vertex.position = (startPoint +
+ subTangent * -width);
vertex.position += offset;
vertex.uv0 = new Vector2(1f, startUVY); // 右侧顶点的UV
vertices.Add(vertex);
- vertex.position = (endPoint +
- subTangent * width);
+ vertex.position = (endPoint +
+ subTangent * width);
vertex.position += offset;
vertex.uv0 = new Vector2(0f, endUVY); // 左侧顶点的UV
vertices.Add(vertex);
-
- vertex.position = (endPoint +
- subTangent * -width);
+
+ vertex.position = (endPoint +
+ subTangent * -width);
vertex.position += offset;
vertex.uv0 = new Vector2(1f, endUVY); // 右侧顶点的UV
vertices.Add(vertex);
@@ -181,25 +181,26 @@ namespace XericLibrary.Runtime.UIGraph
/// 构建网格对象
/// 该线路片段索引(比如第一段线应该是0)
/// 该片段顶点
- public static void AddSingleLineSegmentVertsAndTriangle_DSL5(this VertexHelper vh, int segmentPartIndex, IEnumerable verts)
+ public static void AddSingleLineSegmentVertsAndTriangle_DSL5(this VertexHelper vh, int segmentPartIndex,
+ IEnumerable verts)
{
foreach (var vert in verts)
vh.AddVert(vert);
int index = segmentPartIndex * 5;
-
+
// 添加线段的两个三角形(构成矩形线段)
- vh.AddTriangle(index, index+1, index+3);
- vh.AddTriangle(index+3, index+2, index);
-
+ vh.AddTriangle(index, index + 1, index + 3);
+ vh.AddTriangle(index + 3, index + 2, index);
+
// 为线段之间添加斜角边缘
// 使用上一个线段的终点和当前线段的起点创建过渡三角形
if (segmentPartIndex != 0)
{
- vh.AddTriangle(index, index-1, index-3);
- vh.AddTriangle(index+1, index-1, index-2);
+ vh.AddTriangle(index, index - 1, index - 3);
+ vh.AddTriangle(index + 1, index - 1, index - 2);
}
}
-
+
///
/// 推送顶点绘制线路
///
@@ -207,56 +208,94 @@ namespace XericLibrary.Runtime.UIGraph
///
///
///
- ///
+ ///
///
- public static void PopulateLineByPointsArray_DSL5(this VertexHelper vh, Vector2[] points, float thickness, bool cycleLoop, Color color, Vector3 offset)
+ ///
+ ///
+ /// 宽x长y
+ ///
+ ///
+ ///
+ ///
+ public static void PopulateLineByPointsArray_DSL5(this VertexHelper vh, Vector2[] points,
+ float thickness, bool cycleLoop, Color lineColor, Vector3 offset,
+ bool enableArrow,
+ Color arrowColor, Vector2 arrowSize, float pointProgress, float arrowPointProgress,
+ bool absProgressPoint = true, bool reverseDir = false)
{
// 至少需要 2 个点才能绘制线条
if (points.Length < 2)
return;
-
+
// 计算线路总长度
var totalLength = points.CalculateTotalLength(cycleLoop);
var currentLength = 0f;
- var vertices = ListPool.Get();
+ var lineVertices = ListPool.Get();
+ var arrowVertices = ListPool.Get();
+ var arrowindices = ListPool.Get();
for (int i = 0; i < points.Length - (cycleLoop ? 0 : 1); i++)
{
- vh.AddSingleLineSegmentVertsAndTriangle_DSL5(i,
- GetSingleLineSegmentVerts_DSL5(vertices, points[i], points[(i + 1) % points.Length], thickness, color, currentLength, out var distance, totalLength, offset));
+ var thisPoint = points[i];
+ var nextPoint = points[(i + 1) % points.Length];
+
+ // 先计算线的矢量参数,以及uv。
+ if (!GetNormalizedVector(thisPoint, nextPoint,
+ out var vector, out var distance, out var normal, out var subTangent))
+ continue;
+ GetCurrentLengthUVY(currentLength, distance, totalLength, out var startUvy, out var endUvy);
+
+ vh.AddSingleLineSegmentVertsAndTriangle_DSL5(i,
+ GetSingleLineSegmentVerts_DSL5(lineVertices, thisPoint, nextPoint, thickness, lineColor, normal,
+ subTangent, startUvy, endUvy, offset));
+
+ if (enableArrow)
+ {
+ PopulateTriangleArrowByPointArray(arrowVertices, thisPoint, nextPoint, arrowColor, arrowSize.y,
+ arrowSize.x, pointProgress, arrowPointProgress, absProgressPoint, reverseDir);
+ arrowindices.AddFaceByConsecutiveVertices(arrowVertices, i * 3, 3, i * 3);
+ }
currentLength += distance;
}
- ListPool.Release(vertices);
+
+ if (enableArrow)
+ {
+ vh.AddUIVertexStream(arrowVertices, arrowindices);
+ }
+ ListPool.Release(lineVertices);
+ ListPool.Release(arrowVertices);
+ ListPool.Release(arrowindices);
}
-
+
#endregion
#region 圆弧过度的线路绘制
// 在简易线路绘制的基础上,修改了转角处的处理
// 线的顶点还是5,但是转角圆弧处理会更细节,叫它 CFAL (中心对齐的圆弧转角直线,center fanshaped arc Line)
-
+
///
/// 在网格构建对象上添加这个直线片段
///
/// 构建网格对象
/// 该线路片段索引(比如第一段线应该是0)
/// 该片段顶点
- public static void AddSingleLineSegmentVertsAndTriangle_CFAL(this VertexHelper vh, int segmentPartIndex, IEnumerable verts)
+ public static void AddSingleLineSegmentVertsAndTriangle_CFAL(this VertexHelper vh, int segmentPartIndex,
+ IEnumerable verts)
{
foreach (var vert in verts)
vh.AddVert(vert);
int index = segmentPartIndex * 5;
-
+
// 添加线段的两个三角形(构成矩形线段)
- vh.AddTriangle(index, index+1, index+3);
- vh.AddTriangle(index+3, index+2, index);
-
+ vh.AddTriangle(index, index + 1, index + 3);
+ vh.AddTriangle(index + 3, index + 2, index);
+
// 为线段之间添加斜角边缘
// 使用上一个线段的终点和当前线段的起点创建过渡三角形
if (segmentPartIndex != 0)
{
- vh.AddTriangle(index, index-1, index-3);
- vh.AddTriangle(index+1, index-1, index-2);
+ vh.AddTriangle(index, index - 1, index - 3);
+ vh.AddTriangle(index + 1, index - 1, index - 2);
}
}
@@ -278,49 +317,50 @@ namespace XericLibrary.Runtime.UIGraph
/// 内圆弧半径
/// 返回线段的距离
/// 包含线段顶点的列表
- public static List GetSingleLineSegmentVerts_CFAL(List vertices, Vector2 startPoint, Vector2 endPoint, Vector2 nextPoint, Vector2 prevPoint,
- float thickness, Color color, float startLength, out float distance, float totalLength, Vector3 offset,
+ public static List GetSingleLineSegmentVerts_CFAL(List vertices, Vector2 startPoint,
+ Vector2 endPoint, Vector2 nextPoint, Vector2 prevPoint,
+ float thickness, Color color, float startLength, out float distance, float totalLength, Vector3 offset,
int chamferSegments = 0, float innerRadius = 0f)
{
if (vertices == null)
throw new Exception("没有指定线段片段顶点容器列表");
vertices.Clear();
-
+
// 创建顶点模板,设置颜色为组件的当前颜色
UIVertex vertex = UIVertex.simpleVert;
vertex.color = color;
- if (!GetNormalizedVector(startPoint, endPoint,
+ if (!GetNormalizedVector(startPoint, endPoint,
out var vector, out distance, out var normal, out var subTangent))
return vertices;
-
+
// 线段单侧宽度
var width = thickness / 2;
-
+
GetCurrentLengthUVY(startLength, distance, totalLength, out var startUVY, out var endUVY);
-
+
// 计算起点和终点的夹角
float startAngle = 0f;
float endAngle = 0f;
-
+
if (prevPoint != startPoint)
{
var prevVector = startPoint - prevPoint;
var prevNormal = prevVector.normalized;
startAngle = Vector2.Angle(normal, -prevNormal);
}
-
+
if (nextPoint != endPoint)
{
var nextVector = nextPoint - endPoint;
var nextNormal = nextVector.normalized;
endAngle = Vector2.Angle(-normal, nextNormal);
}
-
+
// 计算顶点偏移量
float startOffset = 0f;
float endOffset = 0f;
-
+
if (Mathf.Abs(startAngle) > 0.1f)
{
if (innerRadius > 0f)
@@ -332,7 +372,7 @@ namespace XericLibrary.Runtime.UIGraph
startOffset = width / Mathf.Sin(startAngle * Mathf.Deg2Rad / 2);
}
}
-
+
if (Mathf.Abs(endAngle) > 0.1f)
{
if (innerRadius > 0f)
@@ -344,46 +384,46 @@ namespace XericLibrary.Runtime.UIGraph
endOffset = width / Mathf.Sin(endAngle * Mathf.Deg2Rad / 2);
}
}
-
+
// 添加起点的左侧顶点
- vertex.position = (startPoint +
- subTangent * width +
- normal * startOffset);
+ vertex.position = (startPoint +
+ subTangent * width +
+ normal * startOffset);
vertex.position += offset;
vertex.uv0 = new Vector2(0f, startUVY);
vertices.Add(vertex);
-
+
// 添加起点的右侧顶点
- vertex.position = (startPoint +
- subTangent * -width +
- normal * startOffset);
+ vertex.position = (startPoint +
+ subTangent * -width +
+ normal * startOffset);
vertex.position += offset;
vertex.uv0 = new Vector2(1f, startUVY);
vertices.Add(vertex);
// 添加终点的左侧顶点
- vertex.position = (endPoint +
- subTangent * width +
- normal * -endOffset);
+ vertex.position = (endPoint +
+ subTangent * width +
+ normal * -endOffset);
vertex.position += offset;
vertex.uv0 = new Vector2(0f, endUVY);
vertices.Add(vertex);
-
+
// 添加终点的右侧顶点
- vertex.position = (endPoint +
- subTangent * -width +
- normal * -endOffset);
+ vertex.position = (endPoint +
+ subTangent * -width +
+ normal * -endOffset);
vertex.position += offset;
vertex.uv0 = new Vector2(1f, endUVY);
vertices.Add(vertex);
// 添加终点的中心点
- vertex.position = (endPoint +
- normal * -endOffset);
+ vertex.position = (endPoint +
+ normal * -endOffset);
vertex.position += offset;
vertex.uv0 = new Vector2(0.5f, endUVY);
vertices.Add(vertex);
-
+
return vertices;
}
@@ -398,40 +438,89 @@ namespace XericLibrary.Runtime.UIGraph
/// 偏移量
/// 倒角细分数量
/// 内圆弧半径
- public static void PopulateLineByPointsArray_CFAL(this VertexHelper vh, Vector2[] points, float thickness, bool cycleLoop, Color color, Vector3 offset,
+ public static void PopulateLineByPointsArray_CFAL(this VertexHelper vh, Vector2[] points, float thickness,
+ bool cycleLoop, Color color, Vector3 offset,
int chamferSegments = 0, float innerRadius = 0f)
{
// 至少需要 2 个点才能绘制线条
if (points.Length < 2)
return;
-
+
// 计算线路总长度
var totalLength = points.CalculateTotalLength(cycleLoop);
var currentLength = 0f;
var vertices = ListPool.Get();
-
+
for (int i = 0; i < points.Length - (cycleLoop ? 0 : 1); i++)
{
var startPoint = points[i];
var endPoint = points[(i + 1) % points.Length];
var prevPoint = i > 0 ? points[i - 1] : cycleLoop ? points[^1] : startPoint;
var nextPoint = points[(i + 2) % points.Length];
-
- vh.AddSingleLineSegmentVertsAndTriangle_CFAL(i,
- GetSingleLineSegmentVerts_CFAL(vertices, startPoint, endPoint, nextPoint, prevPoint,
- thickness, color, currentLength, out var distance, totalLength, offset,
+
+ vh.AddSingleLineSegmentVertsAndTriangle_CFAL(i,
+ GetSingleLineSegmentVerts_CFAL(vertices, startPoint, endPoint, nextPoint, prevPoint,
+ thickness, color, currentLength, out var distance, totalLength, offset,
chamferSegments, innerRadius));
currentLength += distance;
}
-
+
ListPool.Release(vertices);
}
-
#endregion
-
+
+ #region 箭头绘制工具
+
+ ///
+ /// 绘制一个三角形箭头
+ ///
+ /// 起点
+ /// 终点
+ /// 颜色
+ /// 箭头的长度
+ /// 箭头的宽度
+ /// 箭头所处坐标相对线的进度,使用绝对距离时,进度为世界单位;使用相对距离时,进度为单位距离
+ /// 箭头的哪部分与所处坐标对齐,0为头部对齐,1为尾部对齐
+ /// 箭头做出坐标是否为绝对距离
+ /// 反转方向
+ ///
+ /// 箭头默认在
+ ///
+ public static List PopulateTriangleArrowByPointArray(List vertices, Vector2 start,
+ Vector2 end, Color color, float sizeL, float sizeW, float pointProgress, float arrowPointProgress,
+ bool absProgressPoint = true, bool reverseDir = false)
+ {
+ GetNormalizedVector(start, end, out var vector, out var length, out var normal, out var tangent,
+ reverseDir);
+
+ var progressPosition = absProgressPoint
+ ? pointProgress * normal
+ : pointProgress * vector;
+ // 加上坐标
+ progressPosition += reverseDir ? end : start;
+ // 加上箭头偏移量
+ progressPosition += arrowPointProgress * sizeL * normal;
+
+ // 绘制箭头
+ UIVertex vertex = UIVertex.simpleVert;
+ vertex.color = color;
+
+ vertex.position = progressPosition;
+ vertices.Add(vertex);
+
+ vertex.position = progressPosition + -sizeL * normal + sizeW * 0.5f * tangent;
+ vertices.Add(vertex);
+ vertex.position += (Vector3)(-sizeW * tangent);
+ vertices.Add(vertex);
+
+ return vertices;
+ }
+
+ #endregion
+
#region 带有顶合并的线路绘制方法
-
+
///
/// 创建线段的顶点数据
/// 每个线段由 5 个顶点组成:
@@ -450,7 +539,9 @@ namespace XericLibrary.Runtime.UIGraph
/// 用于添加顶点的 VertexHelper 对象
/// 当前线段起点在线路中的累积长度
/// 线路的总长度
- public static void CreateLineSegment_CFAL(this VertexHelper vh, Vector2 startPoint, Vector2 endPoint, float angle0, float angle3, float thickness, bool center, Vector2 rectSize, Color color, float startLength, float totalLength)
+ public static void CreateLineSegment_CFAL(this VertexHelper vh, Vector2 startPoint, Vector2 endPoint,
+ float angle0, float angle3, float thickness, bool center, Vector2 rectSize, Color color, float startLength,
+ float totalLength)
{
// 计算偏移量:如果需要居中显示,则偏移到组件中心
Vector2 offset = center ? (rectSize / 2) : Vector2.zero;
@@ -466,39 +557,44 @@ namespace XericLibrary.Runtime.UIGraph
// 线段单侧宽度
var width = thickness / 2;
//顶点偏移量,根据夹角计算内侧交点相对坐标点应该退后的距离
- var pointOffset1 = Mathf.Abs(angle0) <= 0.1f ? 0 : width / Mathf.Sin(angle0 * Mathf.Deg2Rad) + (angle0 > 90 ? width : 0);
- var pointOffset2 = Mathf.Abs(angle3) <= 0.1f ? 0 : width / Mathf.Sin(angle3 * Mathf.Deg2Rad) + (angle3 > 90 ? width : 0);
- Debug.Log($"{angle0} = {Mathf.Sin(angle0 * Mathf.Deg2Rad)} , {angle3} = {Mathf.Sin(angle3 * Mathf.Deg2Rad)}");
+ var pointOffset1 = Mathf.Abs(angle0) <= 0.1f
+ ? 0
+ : width / Mathf.Sin(angle0 * Mathf.Deg2Rad) + (angle0 > 90 ? width : 0);
+ var pointOffset2 = Mathf.Abs(angle3) <= 0.1f
+ ? 0
+ : width / Mathf.Sin(angle3 * Mathf.Deg2Rad) + (angle3 > 90 ? width : 0);
+ Debug.Log(
+ $"{angle0} = {Mathf.Sin(angle0 * Mathf.Deg2Rad)} , {angle3} = {Mathf.Sin(angle3 * Mathf.Deg2Rad)}");
// 计算起点和终点的UV坐标Y值
float startUVY = totalLength > 0 ? startLength / totalLength : 0f;
float endUVY = totalLength > 0 ? (startLength + distance) / totalLength : 0f;
-
- vertex.position = (Vector3)(startPoint +
- subTangent * width +
+
+ vertex.position = (Vector3)(startPoint +
+ subTangent * width +
normal * pointOffset1) - (Vector3)offset;
vertex.uv0 = new Vector2(0f, startUVY); // 左侧顶点的UV
vh.AddVert(vertex);
-
- vertex.position = (Vector3)(startPoint +
- subTangent * -width +
+
+ vertex.position = (Vector3)(startPoint +
+ subTangent * -width +
normal * pointOffset1) - (Vector3)offset;
vertex.uv0 = new Vector2(1f, startUVY); // 右侧顶点的UV
vh.AddVert(vertex);
- vertex.position = (Vector3)(endPoint +
- subTangent * width +
+ vertex.position = (Vector3)(endPoint +
+ subTangent * width +
normal * -pointOffset2) - (Vector3)offset;
vertex.uv0 = new Vector2(0f, endUVY); // 左侧顶点的UV
vh.AddVert(vertex);
-
- vertex.position = (Vector3)(endPoint +
- subTangent * -width +
+
+ vertex.position = (Vector3)(endPoint +
+ subTangent * -width +
normal * -pointOffset2) - (Vector3)offset;
vertex.uv0 = new Vector2(1f, endUVY); // 右侧顶点的UV
vh.AddVert(vertex);
// 添加终点的中心点,用于连接后续线段
- vertex.position = (Vector3)(endPoint +
+ vertex.position = (Vector3)(endPoint +
normal * -pointOffset2) - (Vector3)offset;
vertex.uv0 = new Vector2(0.5f, endUVY); // 中心点的UV
vh.AddVert(vertex);
@@ -513,19 +609,20 @@ namespace XericLibrary.Runtime.UIGraph
u = (pos.x - rect.xMin) / rect.width;
v = (pos.y - rect.yMin) / rect.height;
}
-
+
public static void Get(this IList vertexList, Vector4 uv2)
{
-
}
#endregion
#region 顶点列表工具
-
- private static readonly Color32 s_DefaultColor = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue);
- private static readonly Vector4 s_DefaultTangent = new Vector4(1f, 0.0f, 0.0f, -1f);
-
+
+ private static readonly Color32 s_DefaultColor =
+ new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue);
+
+ private static readonly Vector4 s_DefaultTangent = new Vector4(1f, 0.0f, 0.0f, -1f);
+
///
/// 添加一个顶点信息
///
@@ -547,6 +644,7 @@ namespace XericLibrary.Runtime.UIGraph
uv3 = uv
});
}
+
///
/// 添加一个三角面索引
///
@@ -560,7 +658,34 @@ namespace XericLibrary.Runtime.UIGraph
indices.Add(index1);
indices.Add(index2);
}
-
+
+ ///
+ /// 向顶点管理器添加顶点列表中的顶点构成的面
+ ///
+ ///
+ ///
+ /// 开始连成面的顶点
+ /// 连成面的顶点范围
+ /// 作为连接面中心的顶点
+ public static void AddFaceByConsecutiveVertices(this ICollection indices, IList vertexList,
+ int startVertexIndex, int faceVertexRange, int centerVertexIndex)
+ {
+ if (faceVertexRange < 3)
+ throw new IndexOutOfRangeException("无法创建小于3个点的面");
+ var length = startVertexIndex + faceVertexRange - 1;
+ for (int i = startVertexIndex + 1; i < length; i++)
+ {
+ if (i < 0 || i > vertexList.Count)
+ throw new IndexOutOfRangeException(
+ $"在向顶点集添加顶点时,从{startVertexIndex}开始的{faceVertexRange}个顶点(以及{centerVertexIndex})可能超出{vertexList.Count}的范围(预定范围{length}),导致构建超出预期");
+ var next = startVertexIndex + 1;
+
+ if (next >= vertexList.Count)
+ return;
+ indices.AddTriangle(centerVertexIndex, startVertexIndex, startVertexIndex + 1);
+ }
+ }
+
#endregion
}
}
\ No newline at end of file
diff --git a/Runtime/Pattern/UIAnyPatternRenderer.cs b/Runtime/Pattern/UIAnyPatternRenderer.cs
index 3205802..c99aaa4 100644
--- a/Runtime/Pattern/UIAnyPatternRenderer.cs
+++ b/Runtime/Pattern/UIAnyPatternRenderer.cs
@@ -3,6 +3,10 @@ using System.Linq;
using UnityEngine;
using UnityEngine.UI;
+#if UNITY_EDITOR
+using UnityEditor;
+#endif
+
namespace XericLibrary.Runtime.UIGraph
{
///
@@ -794,6 +798,19 @@ namespace XericLibrary.Runtime.UIGraph
base.OnValidate();
isDirty = true;
}
+
+
+ [MenuItem("GameObject/Xeric Library/UI/UIAnyPatternRenderer", false, 10)]
+ private static void CreateGameObject()
+ {
+ GameObject newObject = new GameObject(nameof(UIAnyPatternRenderer), typeof(UIAnyPatternRenderer));
+
+ if (Selection.activeGameObject != null)
+ newObject.transform.SetParent(Selection.activeGameObject.transform);
+
+ Undo.RegisterCreatedObjectUndo(newObject, $"Create {nameof(UIAnyPatternRenderer)}");
+ Selection.activeObject = newObject;
+ }
#endif
}
diff --git a/Runtime/Pattern/UILineRenderer.cs b/Runtime/Pattern/UILineRenderer.cs
index 403f25b..98adbfd 100644
--- a/Runtime/Pattern/UILineRenderer.cs
+++ b/Runtime/Pattern/UILineRenderer.cs
@@ -3,6 +3,10 @@ using UnityEngine;
using UnityEngine.Serialization;
using UnityEngine.UI;
+#if UNITY_EDITOR
+using UnityEditor;
+#endif
+
namespace XericLibrary.Runtime.UIGraph
{
///
@@ -23,12 +27,34 @@ namespace XericLibrary.Runtime.UIGraph
public List points = new List();
private Vector2[] _points;
+ ///
+ /// 线路宽度
+ ///
public float thickness = 10f;
+ ///
+ /// 居中对齐
+ ///
public bool center = true;
+ ///
+ /// 循环线路
+ ///
public bool cycleLoop = false;
+ ///
+ /// 启用额外绘制的矢量箭头
+ ///
+ public bool enableVectorArrow = false;
+ ///
+ /// 矢量箭头尺寸(宽长)
+ ///
+ public Vector2 vectorArrowSize = Vector2.one;
+
+ public bool absVectorProgress = true;
+ public float vectorProgress = 15f;
+ public float vectorArrowProgress = 0.5f;
+ public bool reverseVector = false;
///
- /// 是否启用倒角功能
+ /// 是/否启用倒角功能
///
public bool useChamfer = false;
@@ -76,7 +102,7 @@ namespace XericLibrary.Runtime.UIGraph
points.Clear();
Refresh();
}
-
+
///
/// 生成线条网格
///
@@ -89,15 +115,18 @@ namespace XericLibrary.Runtime.UIGraph
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);
- }
+ {
+ vh.PopulateLineByPointsArray_DSL5(_points, thickness, cycleLoop, color, offset,
+ enableVectorArrow,
+ color, vectorArrowSize, vectorProgress, vectorArrowProgress, absVectorProgress, reverseVector);
+ }
return;
@@ -138,5 +167,20 @@ namespace XericLibrary.Runtime.UIGraph
}
}
}
+
+#if UNITY_EDITOR
+
+ [MenuItem("GameObject/Xeric Library/UI/UILineRenderer", false, 10)]
+ private static void CreateGameObject()
+ {
+ GameObject newObject = new GameObject(nameof(UILineRenderer), typeof(UILineRenderer));
+
+ if (Selection.activeGameObject != null)
+ newObject.transform.SetParent(Selection.activeGameObject.transform);
+
+ Undo.RegisterCreatedObjectUndo(newObject, $"Create {nameof(UILineRenderer)}");
+ Selection.activeObject = newObject;
+ }
+#endif
}
-}
\ No newline at end of file
+}
diff --git a/Runtime/Pattern/UIPatternRenderer.cs b/Runtime/Pattern/UIPatternRenderer.cs
index c4e3771..4763832 100644
--- a/Runtime/Pattern/UIPatternRenderer.cs
+++ b/Runtime/Pattern/UIPatternRenderer.cs
@@ -7,6 +7,10 @@ using UnityEngine.Serialization;
using UnityEngine.UI;
using XericLibrary.Runtime.Debuger;
using XericLibrary.Runtime.MacroLibrary;
+
+#if UNITY_EDITOR
+using UnityEditor;
+#endif
#if ODIN_INSPECTOR
using Sirenix.OdinInspector;
#endif
@@ -315,6 +319,19 @@ namespace XericLibrary.Runtime.UIGraph
BorderColorLinear = borderColor2;
FillColor = fillColor;
}
+
+
+ [MenuItem("GameObject/Xeric Library/UI/UIPatternRenderer", false, 10)]
+ private static void CreateGameObject()
+ {
+ GameObject newObject = new GameObject(nameof(UIPatternRenderer), typeof(UIPatternRenderer));
+
+ if (Selection.activeGameObject != null)
+ newObject.transform.SetParent(Selection.activeGameObject.transform);
+
+ Undo.RegisterCreatedObjectUndo(newObject, $"Create {nameof(UIPatternRenderer)}");
+ Selection.activeObject = newObject;
+ }
#endif
}
}
\ No newline at end of file
diff --git a/Runtime/Pattern/XericRendererComponent.cs b/Runtime/Pattern/XericRendererComponent.cs
index f31dbb3..cc8ba41 100644
--- a/Runtime/Pattern/XericRendererComponent.cs
+++ b/Runtime/Pattern/XericRendererComponent.cs
@@ -3,6 +3,7 @@ using System.Linq;
using UnityEngine;
using UnityEngine.Pool;
using UnityEngine.UI;
+using XericLibrary.Runtime.MacroLibrary;
namespace XericLibrary.Runtime.UIGraph
{
@@ -21,6 +22,7 @@ namespace XericLibrary.Runtime.UIGraph
private readonly List _indexList = new List();
// 阵列原点
private List _arrayTransformList = new List();
+ private List _arrayColorList = new List();
// 中间数据
private List _temp_vertexList = new List();
private List _temp_indexList = new List();
@@ -89,14 +91,26 @@ namespace XericLibrary.Runtime.UIGraph
///
/// 偏移
/// 角度
- public int AddArrayModifier(Vector3 offset, float angle)
+ public int AddArrayModifier(Vector2 offset, float angle, float size)
{
var index = _arrayTransformList.Count;
- _arrayTransformList.Add(new Vector4(offset.x, offset.y, offset.z, angle));
+ _arrayTransformList.Add(new Vector4(offset.x, offset.y, angle, size));
Refresh();
return index;
}
+ ///
+ /// 设置阵列节点
+ ///
+ ///
+ public void SetArrayModifier(IList trans)
+ {
+ if (trans == null)
+ return;
+ _arrayTransformList.Clear();
+ _arrayTransformList.AddRange(trans);
+ }
+
///
/// 清空阵列节点
///
@@ -105,15 +119,62 @@ namespace XericLibrary.Runtime.UIGraph
_arrayTransformList.Clear();
Refresh();
}
-
- public bool ModifyArrayModifier(int index, Vector3 offset, float angle)
+
+ ///
+ /// 修改阵列节点
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public bool ModifyArrayModifier(int index, Vector2 offset, float angle, float size)
{
if (index < 0 || index >= _arrayTransformList.Count)
return false;
- _arrayTransformList[index] = new Vector4(offset.x, offset.y, offset.z, angle);
+ _arrayTransformList[index] = new Vector4(offset.x, offset.y, angle, size);
Refresh();
return true;
}
+
+ public IList GetArrayModifier() => _arrayTransformList;
+
+ ///
+ /// 添加颜色
+ ///
+ ///
+ public void AddColor(Color color) => _arrayColorList.Add(color);
+
+ ///
+ /// 添加颜色
+ ///
+ ///
+ public void AddColor(Color32 color) => _arrayColorList.Add(color);
+
+ ///
+ /// 设置颜色节点
+ ///
+ ///
+ ///
+ public void SetColor(int index, Color color) => _arrayColorList.SetAtIndex(color, index);
+
+ ///
+ /// 设置颜色节点
+ ///
+ ///
+ ///
+ public void SetColor(int index, Color32 color) => _arrayColorList.SetAtIndex(color, index);
+
+ ///
+ /// 清空颜色
+ ///
+ public void ClearArrayColor() => _arrayColorList.Clear();
+
+ ///
+ /// 获取颜色列表
+ ///
+ ///
+ public IList GetArrayColor() => _arrayColorList;
#endregion
@@ -147,19 +208,27 @@ namespace XericLibrary.Runtime.UIGraph
{
_temp_vertexList.AddRange(_vertexList.Select(a =>
{
- var newPos = a.position;
- if (transform.w != 0)
+ Vector2 newPos = a.position;
+ if (transform.z != 0)
{
- var rot = Quaternion.Euler(0, 0, transform.w);
+ var rot = Quaternion.Euler(0, 0, transform.z);
newPos = rot * newPos;
}
- newPos += (Vector3)transform;
+ if (transform.z > 0)
+ newPos *= transform.w;
+ newPos += (Vector2)transform;
+ var newColor = a.color;
+ if (index < _arrayColorList.Count && !default(Color32).Equals(_arrayColorList[index]))
+ {
+ newColor = _arrayColorList[index];
+ }
+
return new UIVertex()
{
position = newPos,
normal = a.normal,
tangent = a.tangent,
- color = a.color,
+ color = newColor,
uv0 = a.uv0,
uv1 = a.uv1,
uv2 = a.uv2,