102 lines
3.2 KiB
C#
102 lines
3.2 KiB
C#
using UnityEngine;
|
|
using System.Collections.Generic;
|
|
|
|
public static class CuttingUtils
|
|
{
|
|
public static int FindNearestEdgePointIndex(Vector2 pos, List<Vector2> edgePoints, out float minDist)
|
|
{
|
|
int nearestIndex = 0;
|
|
minDist = float.MaxValue;
|
|
|
|
for (int i = 0; i < edgePoints.Count; i++)
|
|
{
|
|
float dist = Vector2.Distance(pos, edgePoints[i]);
|
|
if (dist < minDist)
|
|
{
|
|
minDist = dist;
|
|
nearestIndex = i;
|
|
}
|
|
}
|
|
return nearestIndex;
|
|
}
|
|
|
|
public static Vector2 GetClosestPointOnSegment(Vector2 a, Vector2 b, Vector2 p)
|
|
{
|
|
Vector2 ab = b - a;
|
|
float t = Vector2.Dot(p - a, ab) / ab.sqrMagnitude;
|
|
t = Mathf.Clamp01(t);
|
|
return a + ab * t;
|
|
}
|
|
|
|
public static int WrapIndex(int index, int count)
|
|
{
|
|
if (index < 0) return count - 2;
|
|
if (index >= count - 1) return 0;
|
|
return index;
|
|
}
|
|
|
|
public static List<Vector2> GetSpritePhysicsShapePoints(SpriteRenderer spriteRenderer)
|
|
{
|
|
List<Vector2> shapePoints = new List<Vector2>();
|
|
spriteRenderer.sprite.GetPhysicsShape(0, shapePoints);
|
|
|
|
if (shapePoints.Count == 0)
|
|
{
|
|
Debug.LogError("目标Sprite没有物理形状点");
|
|
return null;
|
|
}
|
|
|
|
return shapePoints;
|
|
}
|
|
|
|
public static (List<Vector2> scaledPoints, List<Vector2> originalPoints) ProcessEdgePoints(
|
|
List<Vector2> shapePoints,
|
|
SpriteRenderer spriteRenderer,
|
|
float edgePointsScale = 1.2f,
|
|
float desiredSegmentLength = 0.1f)
|
|
{
|
|
if (shapePoints == null || shapePoints.Count == 0) return (null, null);
|
|
|
|
List<Vector2> scaledPoints = new List<Vector2>();
|
|
List<Vector2> originalPoints = new List<Vector2>();
|
|
|
|
// 计算中心点
|
|
Vector2 center = Vector2.zero;
|
|
foreach (Vector2 point in shapePoints)
|
|
{
|
|
center += point;
|
|
}
|
|
center /= shapePoints.Count;
|
|
|
|
// 处理每个线段
|
|
for (int i = 0; i < shapePoints.Count; i++)
|
|
{
|
|
Vector2 p1 = spriteRenderer.transform.TransformPoint(shapePoints[i]);
|
|
Vector2 p2 = spriteRenderer.transform.TransformPoint(shapePoints[(i + 1) % shapePoints.Count]);
|
|
|
|
Vector2 scaledP1 = center + (p1 - center) * edgePointsScale;
|
|
Vector2 scaledP2 = center + (p2 - center) * edgePointsScale;
|
|
|
|
float segmentLength = Vector2.Distance(scaledP1, scaledP2);
|
|
int steps = Mathf.Max(1, Mathf.CeilToInt(segmentLength / desiredSegmentLength));
|
|
|
|
for (int s = 0; s < steps; s++)
|
|
{
|
|
float t = (float)s / steps;
|
|
Vector2 interpolated = Vector2.Lerp(scaledP1, scaledP2, t);
|
|
Vector2 originalInterpolated = Vector2.Lerp(p1, p2, t);
|
|
scaledPoints.Add(interpolated);
|
|
originalPoints.Add(originalInterpolated);
|
|
}
|
|
}
|
|
|
|
// 确保首尾相连
|
|
if ((scaledPoints[0] - scaledPoints[scaledPoints.Count - 1]).sqrMagnitude > 0.0001f)
|
|
{
|
|
scaledPoints.Add(scaledPoints[0]);
|
|
originalPoints.Add(originalPoints[0]);
|
|
}
|
|
|
|
return (scaledPoints, originalPoints);
|
|
}
|
|
} |