This commit is contained in:
2026-06-29 14:36:02 +08:00
parent d938aa9929
commit 6af5616e50
5 changed files with 406 additions and 134 deletions
+173 -48
View File
@@ -54,7 +54,8 @@ namespace XericLibrary.Runtime.UIGraph
/// <param name="center">是否要居中显示</param> /// <param name="center">是否要居中显示</param>
/// <param name="rectSize">整个绘制矩形范围的尺寸</param> /// <param name="rectSize">整个绘制矩形范围的尺寸</param>
/// <returns></returns> /// <returns></returns>
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);
/// <summary> /// <summary>
/// 获取两个点之间的法线,副法线 /// 获取两个点之间的法线,副法线
@@ -65,11 +66,13 @@ namespace XericLibrary.Runtime.UIGraph
/// <param name="distance">两点间距离</param> /// <param name="distance">两点间距离</param>
/// <param name="normal">起点到终点的法线</param> /// <param name="normal">起点到终点的法线</param>
/// <param name="subTangent">垂直与起点到终点的法线(法线左转90)</param> /// <param name="subTangent">垂直与起点到终点的法线(法线左转90)</param>
/// <param name="reverseVector">反转矢量</param>
/// <returns></returns> /// <returns></returns>
private static bool GetNormalizedVector(Vector2 startPoint, Vector2 endPoint, private static bool GetNormalizedVector(Vector2 startPoint, Vector2 endPoint,
out Vector2 vector, out float distance, out Vector2 normal, out Vector2 subTangent) 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; distance = vector.magnitude;
normal = Vector2.zero; normal = Vector2.zero;
subTangent = Vector2.zero; subTangent = Vector2.zero;
@@ -96,7 +99,8 @@ namespace XericLibrary.Runtime.UIGraph
/// <param name="totalLength">总线路的长度</param> /// <param name="totalLength">总线路的长度</param>
/// <param name="startUVY">起点处的uv y</param> /// <param name="startUVY">起点处的uv y</param>
/// <param name="endUVY">终点处的uv y</param> /// <param name="endUVY">终点处的uv y</param>
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; startUVY = totalLength > 0 ? startLength / totalLength : 0f;
endUVY = totalLength > 0 ? (startLength + currentLength) / totalLength : 0f; endUVY = totalLength > 0 ? (startLength + currentLength) / totalLength : 0f;
@@ -124,8 +128,10 @@ namespace XericLibrary.Runtime.UIGraph
/// <param name="color">线条的颜色</param> /// <param name="color">线条的颜色</param>
/// <param name="startLength">当前线段起点在线路中的累积长度</param> /// <param name="startLength">当前线段起点在线路中的累积长度</param>
/// <param name="totalLength">线路的总长度</param> /// <param name="totalLength">线路的总长度</param>
public static List<UIVertex> GetSingleLineSegmentVerts_DSL5(List<UIVertex> vertices, Vector2 startPoint, Vector2 endPoint, public static List<UIVertex> GetSingleLineSegmentVerts_DSL5(List<UIVertex> vertices, Vector2 startPoint,
float thickness, Color color, float startLength, out float distance, float totalLength, Vector3 offset) Vector2 endPoint,
float thickness, Color color, Vector2 normal, Vector2 subTangent, float startUVY, float endUVY,
Vector3 offset)
{ {
if (vertices == null) if (vertices == null)
throw new Exception("没有指定线段片段顶点容器列表"); throw new Exception("没有指定线段片段顶点容器列表");
@@ -134,35 +140,29 @@ namespace XericLibrary.Runtime.UIGraph
UIVertex vertex = UIVertex.simpleVert; UIVertex vertex = UIVertex.simpleVert;
vertex.color = color; vertex.color = color;
if (!GetNormalizedVector(startPoint, endPoint,
out var vector, out distance, out var normal, out var subTangent))
return vertices;
// 线段单侧宽度 // 线段单侧宽度
var width = thickness / 2; var width = thickness / 2;
GetCurrentLengthUVY(startLength, distance, totalLength, out var startUVY, out var endUVY);
vertex.position = (startPoint + vertex.position = (startPoint +
subTangent * width); subTangent * width);
vertex.position += offset; vertex.position += offset;
vertex.uv0 = new Vector2(0f, startUVY); // 左侧顶点的UV vertex.uv0 = new Vector2(0f, startUVY); // 左侧顶点的UV
vertices.Add(vertex); vertices.Add(vertex);
vertex.position = (startPoint + vertex.position = (startPoint +
subTangent * -width); subTangent * -width);
vertex.position += offset; vertex.position += offset;
vertex.uv0 = new Vector2(1f, startUVY); // 右侧顶点的UV vertex.uv0 = new Vector2(1f, startUVY); // 右侧顶点的UV
vertices.Add(vertex); vertices.Add(vertex);
vertex.position = (endPoint + vertex.position = (endPoint +
subTangent * width); subTangent * width);
vertex.position += offset; vertex.position += offset;
vertex.uv0 = new Vector2(0f, endUVY); // 左侧顶点的UV vertex.uv0 = new Vector2(0f, endUVY); // 左侧顶点的UV
vertices.Add(vertex); vertices.Add(vertex);
vertex.position = (endPoint + vertex.position = (endPoint +
subTangent * -width); subTangent * -width);
vertex.position += offset; vertex.position += offset;
vertex.uv0 = new Vector2(1f, endUVY); // 右侧顶点的UV vertex.uv0 = new Vector2(1f, endUVY); // 右侧顶点的UV
vertices.Add(vertex); vertices.Add(vertex);
@@ -181,22 +181,23 @@ namespace XericLibrary.Runtime.UIGraph
/// <param name="vh">构建网格对象</param> /// <param name="vh">构建网格对象</param>
/// <param name="segmentPartIndex">该线路片段索引(比如第一段线应该是0)</param> /// <param name="segmentPartIndex">该线路片段索引(比如第一段线应该是0)</param>
/// <param name="verts">该片段顶点</param> /// <param name="verts">该片段顶点</param>
public static void AddSingleLineSegmentVertsAndTriangle_DSL5(this VertexHelper vh, int segmentPartIndex, IEnumerable<UIVertex> verts) public static void AddSingleLineSegmentVertsAndTriangle_DSL5(this VertexHelper vh, int segmentPartIndex,
IEnumerable<UIVertex> verts)
{ {
foreach (var vert in verts) foreach (var vert in verts)
vh.AddVert(vert); vh.AddVert(vert);
int index = segmentPartIndex * 5; int index = segmentPartIndex * 5;
// 添加线段的两个三角形(构成矩形线段) // 添加线段的两个三角形(构成矩形线段)
vh.AddTriangle(index, index+1, index+3); vh.AddTriangle(index, index + 1, index + 3);
vh.AddTriangle(index+3, index+2, index); vh.AddTriangle(index + 3, index + 2, index);
// 为线段之间添加斜角边缘 // 为线段之间添加斜角边缘
// 使用上一个线段的终点和当前线段的起点创建过渡三角形 // 使用上一个线段的终点和当前线段的起点创建过渡三角形
if (segmentPartIndex != 0) if (segmentPartIndex != 0)
{ {
vh.AddTriangle(index, index-1, index-3); vh.AddTriangle(index, index - 1, index - 3);
vh.AddTriangle(index+1, index-1, index-2); vh.AddTriangle(index + 1, index - 1, index - 2);
} }
} }
@@ -207,9 +208,20 @@ namespace XericLibrary.Runtime.UIGraph
/// <param name="points"></param> /// <param name="points"></param>
/// <param name="thickness"></param> /// <param name="thickness"></param>
/// <param name="cycleLoop"></param> /// <param name="cycleLoop"></param>
/// <param name="color"></param> /// <param name="lineColor"></param>
/// <param name="offset"></param> /// <param name="offset"></param>
public static void PopulateLineByPointsArray_DSL5(this VertexHelper vh, Vector2[] points, float thickness, bool cycleLoop, Color color, Vector3 offset) /// <param name="enableArrow"></param>
/// <param name="arrowColor"></param>
/// <param name="arrowSize">宽x长y</param>
/// <param name="pointProgress"></param>
/// <param name="arrowPointProgress"></param>
/// <param name="absProgressPoint"></param>
/// <param name="reverseDir"></param>
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 个点才能绘制线条 // 至少需要 2 个点才能绘制线条
if (points.Length < 2) if (points.Length < 2)
@@ -218,14 +230,40 @@ namespace XericLibrary.Runtime.UIGraph
// 计算线路总长度 // 计算线路总长度
var totalLength = points.CalculateTotalLength(cycleLoop); var totalLength = points.CalculateTotalLength(cycleLoop);
var currentLength = 0f; var currentLength = 0f;
var vertices = ListPool<UIVertex>.Get(); var lineVertices = ListPool<UIVertex>.Get();
var arrowVertices = ListPool<UIVertex>.Get();
var arrowindices = ListPool<int>.Get();
for (int i = 0; i < points.Length - (cycleLoop ? 0 : 1); i++) for (int i = 0; i < points.Length - (cycleLoop ? 0 : 1); i++)
{ {
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, vh.AddSingleLineSegmentVertsAndTriangle_DSL5(i,
GetSingleLineSegmentVerts_DSL5(vertices, points[i], points[(i + 1) % points.Length], thickness, color, currentLength, out var distance, totalLength, offset)); 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; currentLength += distance;
} }
ListPool<UIVertex>.Release(vertices);
if (enableArrow)
{
vh.AddUIVertexStream(arrowVertices, arrowindices);
}
ListPool<UIVertex>.Release(lineVertices);
ListPool<UIVertex>.Release(arrowVertices);
ListPool<int>.Release(arrowindices);
} }
#endregion #endregion
@@ -241,22 +279,23 @@ namespace XericLibrary.Runtime.UIGraph
/// <param name="vh">构建网格对象</param> /// <param name="vh">构建网格对象</param>
/// <param name="segmentPartIndex">该线路片段索引(比如第一段线应该是0)</param> /// <param name="segmentPartIndex">该线路片段索引(比如第一段线应该是0)</param>
/// <param name="verts">该片段顶点</param> /// <param name="verts">该片段顶点</param>
public static void AddSingleLineSegmentVertsAndTriangle_CFAL(this VertexHelper vh, int segmentPartIndex, IEnumerable<UIVertex> verts) public static void AddSingleLineSegmentVertsAndTriangle_CFAL(this VertexHelper vh, int segmentPartIndex,
IEnumerable<UIVertex> verts)
{ {
foreach (var vert in verts) foreach (var vert in verts)
vh.AddVert(vert); vh.AddVert(vert);
int index = segmentPartIndex * 5; int index = segmentPartIndex * 5;
// 添加线段的两个三角形(构成矩形线段) // 添加线段的两个三角形(构成矩形线段)
vh.AddTriangle(index, index+1, index+3); vh.AddTriangle(index, index + 1, index + 3);
vh.AddTriangle(index+3, index+2, index); vh.AddTriangle(index + 3, index + 2, index);
// 为线段之间添加斜角边缘 // 为线段之间添加斜角边缘
// 使用上一个线段的终点和当前线段的起点创建过渡三角形 // 使用上一个线段的终点和当前线段的起点创建过渡三角形
if (segmentPartIndex != 0) if (segmentPartIndex != 0)
{ {
vh.AddTriangle(index, index-1, index-3); vh.AddTriangle(index, index - 1, index - 3);
vh.AddTriangle(index+1, index-1, index-2); vh.AddTriangle(index + 1, index - 1, index - 2);
} }
} }
@@ -278,7 +317,8 @@ namespace XericLibrary.Runtime.UIGraph
/// <param name="innerRadius">内圆弧半径</param> /// <param name="innerRadius">内圆弧半径</param>
/// <param name="distance">返回线段的距离</param> /// <param name="distance">返回线段的距离</param>
/// <returns>包含线段顶点的列表</returns> /// <returns>包含线段顶点的列表</returns>
public static List<UIVertex> GetSingleLineSegmentVerts_CFAL(List<UIVertex> vertices, Vector2 startPoint, Vector2 endPoint, Vector2 nextPoint, Vector2 prevPoint, public static List<UIVertex> GetSingleLineSegmentVerts_CFAL(List<UIVertex> vertices, Vector2 startPoint,
Vector2 endPoint, Vector2 nextPoint, Vector2 prevPoint,
float thickness, Color color, float startLength, out float distance, float totalLength, Vector3 offset, float thickness, Color color, float startLength, out float distance, float totalLength, Vector3 offset,
int chamferSegments = 0, float innerRadius = 0f) int chamferSegments = 0, float innerRadius = 0f)
{ {
@@ -347,39 +387,39 @@ namespace XericLibrary.Runtime.UIGraph
// 添加起点的左侧顶点 // 添加起点的左侧顶点
vertex.position = (startPoint + vertex.position = (startPoint +
subTangent * width + subTangent * width +
normal * startOffset); normal * startOffset);
vertex.position += offset; vertex.position += offset;
vertex.uv0 = new Vector2(0f, startUVY); vertex.uv0 = new Vector2(0f, startUVY);
vertices.Add(vertex); vertices.Add(vertex);
// 添加起点的右侧顶点 // 添加起点的右侧顶点
vertex.position = (startPoint + vertex.position = (startPoint +
subTangent * -width + subTangent * -width +
normal * startOffset); normal * startOffset);
vertex.position += offset; vertex.position += offset;
vertex.uv0 = new Vector2(1f, startUVY); vertex.uv0 = new Vector2(1f, startUVY);
vertices.Add(vertex); vertices.Add(vertex);
// 添加终点的左侧顶点 // 添加终点的左侧顶点
vertex.position = (endPoint + vertex.position = (endPoint +
subTangent * width + subTangent * width +
normal * -endOffset); normal * -endOffset);
vertex.position += offset; vertex.position += offset;
vertex.uv0 = new Vector2(0f, endUVY); vertex.uv0 = new Vector2(0f, endUVY);
vertices.Add(vertex); vertices.Add(vertex);
// 添加终点的右侧顶点 // 添加终点的右侧顶点
vertex.position = (endPoint + vertex.position = (endPoint +
subTangent * -width + subTangent * -width +
normal * -endOffset); normal * -endOffset);
vertex.position += offset; vertex.position += offset;
vertex.uv0 = new Vector2(1f, endUVY); vertex.uv0 = new Vector2(1f, endUVY);
vertices.Add(vertex); vertices.Add(vertex);
// 添加终点的中心点 // 添加终点的中心点
vertex.position = (endPoint + vertex.position = (endPoint +
normal * -endOffset); normal * -endOffset);
vertex.position += offset; vertex.position += offset;
vertex.uv0 = new Vector2(0.5f, endUVY); vertex.uv0 = new Vector2(0.5f, endUVY);
vertices.Add(vertex); vertices.Add(vertex);
@@ -398,7 +438,8 @@ namespace XericLibrary.Runtime.UIGraph
/// <param name="offset">偏移量</param> /// <param name="offset">偏移量</param>
/// <param name="chamferSegments">倒角细分数量</param> /// <param name="chamferSegments">倒角细分数量</param>
/// <param name="innerRadius">内圆弧半径</param> /// <param name="innerRadius">内圆弧半径</param>
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) int chamferSegments = 0, float innerRadius = 0f)
{ {
// 至少需要 2 个点才能绘制线条 // 至少需要 2 个点才能绘制线条
@@ -427,6 +468,54 @@ namespace XericLibrary.Runtime.UIGraph
ListPool<UIVertex>.Release(vertices); ListPool<UIVertex>.Release(vertices);
} }
#endregion
#region 箭头绘制工具
/// <summary>
/// 绘制一个三角形箭头
/// </summary>
/// <param name="start">起点</param>
/// <param name="end">终点</param>
/// <param name="color">颜色</param>
/// <param name="sizeL">箭头的长度</param>
/// <param name="sizeW">箭头的宽度</param>
/// <param name="pointProgress">箭头所处坐标相对线的进度,使用绝对距离时,进度为世界单位;使用相对距离时,进度为单位距离</param>
/// <param name="arrowPointProgress">箭头的哪部分与所处坐标对齐,0为头部对齐,1为尾部对齐</param>
/// <param name="absProgressPoint">箭头做出坐标是否为绝对距离</param>
/// <param name="reverseDir">反转方向</param>
/// <remarks>
/// 箭头默认在
/// </remarks>
public static List<UIVertex> PopulateTriangleArrowByPointArray(List<UIVertex> 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 #endregion
@@ -450,7 +539,9 @@ namespace XericLibrary.Runtime.UIGraph
/// <param name="vh">用于添加顶点的 VertexHelper 对象</param> /// <param name="vh">用于添加顶点的 VertexHelper 对象</param>
/// <param name="startLength">当前线段起点在线路中的累积长度</param> /// <param name="startLength">当前线段起点在线路中的累积长度</param>
/// <param name="totalLength">线路的总长度</param> /// <param name="totalLength">线路的总长度</param>
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; Vector2 offset = center ? (rectSize / 2) : Vector2.zero;
@@ -466,9 +557,14 @@ namespace XericLibrary.Runtime.UIGraph
// 线段单侧宽度 // 线段单侧宽度
var width = thickness / 2; var width = thickness / 2;
//顶点偏移量,根据夹角计算内侧交点相对坐标点应该退后的距离 //顶点偏移量,根据夹角计算内侧交点相对坐标点应该退后的距离
var pointOffset1 = Mathf.Abs(angle0) <= 0.1f ? 0 : width / Mathf.Sin(angle0 * Mathf.Deg2Rad) + (angle0 > 90 ? width : 0); var pointOffset1 = Mathf.Abs(angle0) <= 0.1f
var pointOffset2 = Mathf.Abs(angle3) <= 0.1f ? 0 : width / Mathf.Sin(angle3 * Mathf.Deg2Rad) + (angle3 > 90 ? width : 0); ? 0
Debug.Log($"{angle0} = {Mathf.Sin(angle0 * Mathf.Deg2Rad)} , {angle3} = {Mathf.Sin(angle3 * Mathf.Deg2Rad)}"); : 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值 // 计算起点和终点的UV坐标Y值
float startUVY = totalLength > 0 ? startLength / totalLength : 0f; float startUVY = totalLength > 0 ? startLength / totalLength : 0f;
float endUVY = totalLength > 0 ? (startLength + distance) / totalLength : 0f; float endUVY = totalLength > 0 ? (startLength + distance) / totalLength : 0f;
@@ -516,14 +612,15 @@ namespace XericLibrary.Runtime.UIGraph
public static void Get(this IList<UIVertex> vertexList, Vector4 uv2) public static void Get(this IList<UIVertex> vertexList, Vector4 uv2)
{ {
} }
#endregion #endregion
#region 顶点列表工具 #region 顶点列表工具
private static readonly Color32 s_DefaultColor = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue); 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 Vector4 s_DefaultTangent = new Vector4(1f, 0.0f, 0.0f, -1f);
/// <summary> /// <summary>
@@ -547,6 +644,7 @@ namespace XericLibrary.Runtime.UIGraph
uv3 = uv uv3 = uv
}); });
} }
/// <summary> /// <summary>
/// 添加一个三角面索引 /// 添加一个三角面索引
/// </summary> /// </summary>
@@ -561,6 +659,33 @@ namespace XericLibrary.Runtime.UIGraph
indices.Add(index2); indices.Add(index2);
} }
/// <summary>
/// 向顶点管理器添加顶点列表中的顶点构成的面
/// </summary>
/// <param name="vh"></param>
/// <param name="vertexList"></param>
/// <param name="startVertexIndex">开始连成面的顶点</param>
/// <param name="faceVertexRange">连成面的顶点范围</param>
/// <param name="centerVertexIndex">作为连接面中心的顶点</param>
public static void AddFaceByConsecutiveVertices(this ICollection<int> indices, IList<UIVertex> 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 #endregion
} }
} }
+17
View File
@@ -3,6 +3,10 @@ using System.Linq;
using UnityEngine; using UnityEngine;
using UnityEngine.UI; using UnityEngine.UI;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace XericLibrary.Runtime.UIGraph namespace XericLibrary.Runtime.UIGraph
{ {
/// <summary> /// <summary>
@@ -794,6 +798,19 @@ namespace XericLibrary.Runtime.UIGraph
base.OnValidate(); base.OnValidate();
isDirty = true; 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 #endif
} }
+48 -4
View File
@@ -3,6 +3,10 @@ using UnityEngine;
using UnityEngine.Serialization; using UnityEngine.Serialization;
using UnityEngine.UI; using UnityEngine.UI;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace XericLibrary.Runtime.UIGraph namespace XericLibrary.Runtime.UIGraph
{ {
/// <summary> /// <summary>
@@ -23,12 +27,34 @@ namespace XericLibrary.Runtime.UIGraph
public List<Vector2> points = new List<Vector2>(); public List<Vector2> points = new List<Vector2>();
private Vector2[] _points; private Vector2[] _points;
/// <summary>
/// 线路宽度
/// </summary>
public float thickness = 10f; public float thickness = 10f;
/// <summary>
/// 居中对齐
/// </summary>
public bool center = true; public bool center = true;
/// <summary>
/// 循环线路
/// </summary>
public bool cycleLoop = false; public bool cycleLoop = false;
/// <summary>
/// 启用额外绘制的矢量箭头
/// </summary>
public bool enableVectorArrow = false;
/// <summary>
/// 矢量箭头尺寸(宽长)
/// </summary>
public Vector2 vectorArrowSize = Vector2.one;
public bool absVectorProgress = true;
public float vectorProgress = 15f;
public float vectorArrowProgress = 0.5f;
public bool reverseVector = false;
/// <summary> /// <summary>
/// 是否启用倒角功能 /// 是/否启用倒角功能
/// </summary> /// </summary>
public bool useChamfer = false; public bool useChamfer = false;
@@ -89,15 +115,18 @@ namespace XericLibrary.Runtime.UIGraph
var offset = XericRendererUtils.SwitchCenterOffset(center, rectTransform.sizeDelta); var offset = XericRendererUtils.SwitchCenterOffset(center, rectTransform.sizeDelta);
_points = points.ToArray(); _points = points.ToArray();
// 切换线路绘制模式
if (useChamfer) if (useChamfer)
{ {
vh.PopulateLineByPointsArray_CFAL(_points, thickness, cycleLoop, color, offset, chamferSegments, innerRadius); vh.PopulateLineByPointsArray_CFAL(_points, thickness, cycleLoop, color, offset, chamferSegments, innerRadius);
} }
else 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; 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
} }
} }
+17
View File
@@ -7,6 +7,10 @@ using UnityEngine.Serialization;
using UnityEngine.UI; using UnityEngine.UI;
using XericLibrary.Runtime.Debuger; using XericLibrary.Runtime.Debuger;
using XericLibrary.Runtime.MacroLibrary; using XericLibrary.Runtime.MacroLibrary;
#if UNITY_EDITOR
using UnityEditor;
#endif
#if ODIN_INSPECTOR #if ODIN_INSPECTOR
using Sirenix.OdinInspector; using Sirenix.OdinInspector;
#endif #endif
@@ -315,6 +319,19 @@ namespace XericLibrary.Runtime.UIGraph
BorderColorLinear = borderColor2; BorderColorLinear = borderColor2;
FillColor = fillColor; 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 #endif
} }
} }
+78 -9
View File
@@ -3,6 +3,7 @@ using System.Linq;
using UnityEngine; using UnityEngine;
using UnityEngine.Pool; using UnityEngine.Pool;
using UnityEngine.UI; using UnityEngine.UI;
using XericLibrary.Runtime.MacroLibrary;
namespace XericLibrary.Runtime.UIGraph namespace XericLibrary.Runtime.UIGraph
{ {
@@ -21,6 +22,7 @@ namespace XericLibrary.Runtime.UIGraph
private readonly List<int> _indexList = new List<int>(); private readonly List<int> _indexList = new List<int>();
// 阵列原点 // 阵列原点
private List<Vector4> _arrayTransformList = new List<Vector4>(); private List<Vector4> _arrayTransformList = new List<Vector4>();
private List<Color32> _arrayColorList = new List<Color32>();
// 中间数据 // 中间数据
private List<UIVertex> _temp_vertexList = new List<UIVertex>(); private List<UIVertex> _temp_vertexList = new List<UIVertex>();
private List<int> _temp_indexList = new List<int>(); private List<int> _temp_indexList = new List<int>();
@@ -89,14 +91,26 @@ namespace XericLibrary.Runtime.UIGraph
/// </summary> /// </summary>
/// <param name="offset">偏移</param> /// <param name="offset">偏移</param>
/// <param name="angle">角度</param> /// <param name="angle">角度</param>
public int AddArrayModifier(Vector3 offset, float angle) public int AddArrayModifier(Vector2 offset, float angle, float size)
{ {
var index = _arrayTransformList.Count; 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(); Refresh();
return index; return index;
} }
/// <summary>
/// 设置阵列节点
/// </summary>
/// <param name="trans"></param>
public void SetArrayModifier(IList<Vector4> trans)
{
if (trans == null)
return;
_arrayTransformList.Clear();
_arrayTransformList.AddRange(trans);
}
/// <summary> /// <summary>
/// 清空阵列节点 /// 清空阵列节点
/// </summary> /// </summary>
@@ -106,15 +120,62 @@ namespace XericLibrary.Runtime.UIGraph
Refresh(); Refresh();
} }
public bool ModifyArrayModifier(int index, Vector3 offset, float angle) /// <summary>
/// 修改阵列节点
/// </summary>
/// <param name="index"></param>
/// <param name="offset"></param>
/// <param name="angle"></param>
/// <param name="size"></param>
/// <returns></returns>
public bool ModifyArrayModifier(int index, Vector2 offset, float angle, float size)
{ {
if (index < 0 || index >= _arrayTransformList.Count) if (index < 0 || index >= _arrayTransformList.Count)
return false; return false;
_arrayTransformList[index] = new Vector4(offset.x, offset.y, offset.z, angle); _arrayTransformList[index] = new Vector4(offset.x, offset.y, angle, size);
Refresh(); Refresh();
return true; return true;
} }
public IList<Vector4> GetArrayModifier() => _arrayTransformList;
/// <summary>
/// 添加颜色
/// </summary>
/// <param name="color"></param>
public void AddColor(Color color) => _arrayColorList.Add(color);
/// <summary>
/// 添加颜色
/// </summary>
/// <param name="color"></param>
public void AddColor(Color32 color) => _arrayColorList.Add(color);
/// <summary>
/// 设置颜色节点
/// </summary>
/// <param name="index"></param>
/// <param name="color"></param>
public void SetColor(int index, Color color) => _arrayColorList.SetAtIndex<Color32>(color, index);
/// <summary>
/// 设置颜色节点
/// </summary>
/// <param name="index"></param>
/// <param name="color"></param>
public void SetColor(int index, Color32 color) => _arrayColorList.SetAtIndex<Color32>(color, index);
/// <summary>
/// 清空颜色
/// </summary>
public void ClearArrayColor() => _arrayColorList.Clear();
/// <summary>
/// 获取颜色列表
/// </summary>
/// <returns></returns>
public IList<Color32> GetArrayColor() => _arrayColorList;
#endregion #endregion
#region 阵列 #region 阵列
@@ -147,19 +208,27 @@ namespace XericLibrary.Runtime.UIGraph
{ {
_temp_vertexList.AddRange(_vertexList.Select(a => _temp_vertexList.AddRange(_vertexList.Select(a =>
{ {
var newPos = a.position; Vector2 newPos = a.position;
if (transform.w != 0) if (transform.z != 0)
{ {
var rot = Quaternion.Euler(0, 0, transform.w); var rot = Quaternion.Euler(0, 0, transform.z);
newPos = rot * newPos; 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() return new UIVertex()
{ {
position = newPos, position = newPos,
normal = a.normal, normal = a.normal,
tangent = a.tangent, tangent = a.tangent,
color = a.color, color = newColor,
uv0 = a.uv0, uv0 = a.uv0,
uv1 = a.uv1, uv1 = a.uv1,
uv2 = a.uv2, uv2 = a.uv2,