From a0e0ab6ea04bb11d4cfa2a656997e6d9d8acde24 Mon Sep 17 00:00:00 2001 From: bottlefish <781230111@qq.com> Date: Fri, 16 May 2025 22:31:11 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E4=B8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/Scenes/CutTest.unity | 127 +++++- .../FixSystemNew/BodyModule/GearFollower.cs | 413 ++++++++---------- 2 files changed, 284 insertions(+), 256 deletions(-) diff --git a/Assets/Scenes/CutTest.unity b/Assets/Scenes/CutTest.unity index f2b16cfe0..8344a3f36 100644 --- a/Assets/Scenes/CutTest.unity +++ b/Assets/Scenes/CutTest.unity @@ -195,7 +195,7 @@ SpriteRenderer: m_LightmapParameters: {fileID: 0} m_SortingLayerID: 0 m_SortingLayer: 0 - m_SortingOrder: 20 + m_SortingOrder: 4 m_Sprite: {fileID: -50090516736836665, guid: 2338fddc038248b4b934bef72357cd13, type: 3} m_Color: {r: 1, g: 1, b: 1, a: 1} m_FlipX: 0 @@ -1180,6 +1180,7 @@ GameObject: - component: {fileID: 1568743344} - component: {fileID: 1568743343} - component: {fileID: 1568743345} + - component: {fileID: 1568743346} m_Layer: 0 m_Name: "\u523B\u5F55\u9F7F\u8F6E" m_TagString: Untagged @@ -1268,12 +1269,116 @@ MonoBehaviour: m_EditorClassIdentifier: targetSpriteRenderer: {fileID: 2110358530} snapDistance: 0.3 - detachDistance: 1 - tractionSpeed: 2 + detachDistance: 2 + tractionSpeed: 0.6 rotationSpeed: 360 - smoothTime: 0.1 - normalColor: {r: 1, g: 1, b: 1, a: 1} - tractionColor: {r: 1, g: 0.92156863, b: 0.015686275, a: 1} + edgeScaleFactor: 1.2 + normalEdgeColor: {r: 1, g: 1, b: 1, a: 1} + cutEdgeColor: {r: 1, g: 0.92156863, b: 0.015686275, a: 1} +--- !u!120 &1568743346 +LineRenderer: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1568743342} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 0 + m_LightProbeUsage: 0 + m_ReflectionProbeUsage: 0 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Positions: + - {x: 0, y: 0, z: 0} + - {x: 0, y: 0, z: 1} + m_Parameters: + serializedVersion: 3 + widthMultiplier: 1 + widthCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 3 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + colorGradient: + serializedVersion: 2 + key0: {r: 1, g: 1, b: 1, a: 1} + key1: {r: 1, g: 1, b: 1, a: 1} + key2: {r: 0, g: 0, b: 0, a: 0} + key3: {r: 0, g: 0, b: 0, a: 0} + key4: {r: 0, g: 0, b: 0, a: 0} + key5: {r: 0, g: 0, b: 0, a: 0} + key6: {r: 0, g: 0, b: 0, a: 0} + key7: {r: 0, g: 0, b: 0, a: 0} + ctime0: 0 + ctime1: 65535 + ctime2: 0 + ctime3: 0 + ctime4: 0 + ctime5: 0 + ctime6: 0 + ctime7: 0 + atime0: 0 + atime1: 65535 + atime2: 0 + atime3: 0 + atime4: 0 + atime5: 0 + atime6: 0 + atime7: 0 + m_Mode: 0 + m_ColorSpace: -1 + m_NumColorKeys: 2 + m_NumAlphaKeys: 2 + numCornerVertices: 0 + numCapVertices: 0 + alignment: 0 + textureMode: 0 + textureScale: {x: 1, y: 1} + shadowBias: 0.5 + generateLightingData: 0 + m_MaskInteraction: 0 + m_UseWorldSpace: 1 + m_Loop: 0 + m_ApplyActiveColorSpace: 1 --- !u!1 &1598025874 GameObject: m_ObjectHideFlags: 0 @@ -1387,11 +1492,6 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 1d60d9d21fc583d41aaa736fc5b2fa72, type: 3} m_Name: m_EditorClassIdentifier: - sawPrefab: {fileID: 8310573110865194826, guid: a82aacc138c51b4459b9d0ef7611ab89, type: 3} - cuttableLayer: - m_Bits: 256 - spawnHeight: 5 - currentSaw: {fileID: 0} --- !u!4 &1599995100 Transform: m_ObjectHideFlags: 0 @@ -1481,7 +1581,7 @@ SpriteRenderer: m_LightmapParameters: {fileID: 0} m_SortingLayerID: 0 m_SortingLayer: 0 - m_SortingOrder: 1 + m_SortingOrder: 3 m_Sprite: {fileID: -1886049787586984079, guid: 2338fddc038248b4b934bef72357cd13, type: 3} m_Color: {r: 1, g: 1, b: 1, a: 1} m_FlipX: 0 @@ -1505,9 +1605,6 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: ad912e1febe29ed499461c26b73ac2b8, type: 3} m_Name: m_EditorClassIdentifier: - spriteRenderer: {fileID: 0} - polygonCollider: {fileID: 0} - originalPoints: [] --- !u!60 &2110358532 PolygonCollider2D: m_ObjectHideFlags: 0 diff --git a/Assets/Scripts/FixSystemNew/BodyModule/GearFollower.cs b/Assets/Scripts/FixSystemNew/BodyModule/GearFollower.cs index 7b7581d90..f6b4a2631 100644 --- a/Assets/Scripts/FixSystemNew/BodyModule/GearFollower.cs +++ b/Assets/Scripts/FixSystemNew/BodyModule/GearFollower.cs @@ -2,150 +2,113 @@ using System.Collections.Generic; using System.Linq; using UnityEngine; -public class GearFollower : MonoBehaviour +[RequireComponent(typeof(LineRenderer))] +public class GearFollowerWithVisualCut : MonoBehaviour { [Header("参数")] - public SpriteRenderer targetSpriteRenderer; // 目标图片 - public float snapDistance = 0.3f; // 距离边缘多少时吸附 - public float detachDistance = 1.0f; // 超过多少距离脱离牵引 - public float tractionSpeed = 5f; // 牵引时沿边缘移动速度 - public float rotationSpeed = 360f; // 齿轮旋转速度(度/秒) - public float smoothTime = 0.1f; // 平滑过渡时间 - public float edgeSmoothTime = 0.02f; // 边缘移动平滑时间 - public float edgeScaleFactor = 1.1f; // 边缘点采样放大倍数 - public int interpolationPoints = 0; // 每两个采样点之间插入的点数 - public float cutTimeThreshold = 0.5f; // 切割时间阈值 - public Color normalColor = Color.white; // 正常状态颜色 - public Color tractionColor = Color.yellow; // 牵引状态颜色 - public Color pathColor = new Color(1f, 1f, 1f, 0.3f); // 路径颜色 - public Color cutPathColor = new Color(0f, 1f, 0f, 0.5f); // 已切割路径颜色 - public float pathWidth = 0.05f; // 路径宽度 + public SpriteRenderer targetSpriteRenderer; + public float snapDistance = 0.3f; + public float detachDistance = 1.0f; + public float tractionSpeed = 2f; + public float rotationSpeed = 360f; + public float edgeScaleFactor = 1.1f; - [Header("反馈效果")] - public float speedMultiplier = 1f; // 切割时速度倍率 - - private List edgePoints; // 边缘路径点 - private int currentEdgeIndex = 0; // 当前吸附边缘点索引 - private SpriteRenderer gearSpriteRenderer; // 齿轮的SpriteRenderer - private Vector2 currentVelocity; // 用于平滑移动 - private float currentRotationVelocity; // 用于平滑旋转 - private LineRenderer pathRenderer; // 路径渲染器 - private float currentPathProgress; // 当前路径进度 - private List cutStates; // 记录每个点是否被切割 - private List cutTimes; // 记录每个点的切割时间 - private float currentCutTime; // 当前点的切割时间 - - private enum State { Follow, Traction } - private State currentState = State.Follow; + public Color normalEdgeColor = Color.white; + public Color cutEdgeColor = Color.yellow; + private List edgePoints; + private int currentEdgeIndex = 0; + private SpriteRenderer gearSpriteRenderer; private Camera mainCamera; - private Vector2 targetEdgePosition; // 目标边缘位置 - private float currentEdgeProgress; // 当前边缘移动进度 - private Vector2 imageCenter; // 图片中心点 - private float imageRadius; // 图片半径 - private Vector2 lastMousePosition; // 上一帧的鼠标位置 + private enum State { Follow, Attract, Traction } + private State currentState = State.Follow; - private float currentSpeed; // 当前速度 - private float targetSpeed; // 目标速度 - private float screenShakeTimer; // 屏幕震动计时器 - private ParticleSystem cutParticleSystem; // 切割粒子系统 - private AudioSource cutAudioSource; // 切割音效 + private bool[] cutSegments; + + private LineRenderer edgeLineRenderer; // 绘制全部边缘 + private LineRenderer cutLineRenderer; // 绘制切割线段 void Start() { mainCamera = Camera.main; gearSpriteRenderer = GetComponent(); - if (gearSpriteRenderer == null) - { - Debug.LogError("齿轮对象缺少SpriteRenderer组件"); - } - - // 计算图片中心点和半径 - if (targetSpriteRenderer != null) - { - imageCenter = targetSpriteRenderer.bounds.center; - // 使用bounds的size计算半径(取较大的值) - imageRadius = Mathf.Max(targetSpriteRenderer.bounds.size.x, targetSpriteRenderer.bounds.size.y) * 0.5f; - } - - // 添加并设置LineRenderer - pathRenderer = gameObject.AddComponent(); - pathRenderer.startWidth = pathWidth; - pathRenderer.endWidth = pathWidth; - pathRenderer.startColor = pathColor; - pathRenderer.endColor = pathColor; - pathRenderer.material = new Material(Shader.Find("Sprites/Default")); - pathRenderer.sortingOrder = 0; - pathRenderer.enabled = false; - LoadEdgePointsFromSprite(); + + cutSegments = new bool[edgePoints.Count - 1]; + + // 设置主边缘线条渲染器 + edgeLineRenderer = GetComponent(); + edgeLineRenderer.positionCount = edgePoints.Count; + edgeLineRenderer.loop = false; + edgeLineRenderer.startWidth = 0.05f; + edgeLineRenderer.endWidth = 0.05f; + edgeLineRenderer.material = new Material(Shader.Find("Sprites/Default")); + edgeLineRenderer.startColor = normalEdgeColor; + edgeLineRenderer.endColor = normalEdgeColor; + edgeLineRenderer.sortingOrder = 3; + + for (int i = 0; i < edgePoints.Count; i++) + { + edgeLineRenderer.SetPosition(i, edgePoints[i]); + } + + // 创建用于切割线段的LineRenderer + GameObject cutLineObj = new GameObject("CutLineRenderer"); + cutLineObj.transform.parent = this.transform; + cutLineRenderer = cutLineObj.AddComponent(); + cutLineRenderer.positionCount = 0; + cutLineRenderer.loop = false; + cutLineRenderer.startWidth = 0.07f; + cutLineRenderer.endWidth = 0.07f; + cutLineRenderer.material = new Material(Shader.Find("Sprites/Default")); + cutLineRenderer.startColor = cutEdgeColor; + cutLineRenderer.endColor = cutEdgeColor; + cutLineRenderer.sortingOrder = 4; } void Update() { Vector2 mouseWorldPos = mainCamera.ScreenToWorldPoint(Input.mousePosition); - Vector2 mouseDelta = mouseWorldPos - lastMousePosition; - lastMousePosition = mouseWorldPos; switch (currentState) { case State.Follow: UpdateFollowState(mouseWorldPos); break; + case State.Attract: + UpdateAttractState(mouseWorldPos); + break; case State.Traction: UpdateTractionState(mouseWorldPos); break; } - // 更新齿轮旋转 - UpdateGearRotation(); - // 更新视觉反馈 - UpdateVisualFeedback(); - // 更新路径显示 - UpdatePathDisplay(); + UpdateGearRotation(); + UpdateVisualFeedback(); + UpdateCutLineRenderer(); + CheckAllSegmentsCut(); } - // 更新齿轮旋转 private void UpdateGearRotation() { if (currentState == State.Traction && Input.GetMouseButton(0)) { - // 在牵引状态下按住左键时旋转 transform.Rotate(0, 0, rotationSpeed * Time.deltaTime); - - // 更新当前点的切割时间 - currentCutTime += Time.deltaTime; - if (currentCutTime >= cutTimeThreshold) - { - if (!cutStates[currentEdgeIndex]) - { - // 触发切割效果 - //TriggerCutEffects(); - } - cutStates[currentEdgeIndex] = true; - cutTimes[currentEdgeIndex] = currentCutTime; - } - } - else - { - currentCutTime = 0f; } } - // 更新视觉反馈 private void UpdateVisualFeedback() { if (gearSpriteRenderer != null) { - gearSpriteRenderer.color = currentState == State.Traction ? tractionColor : normalColor; + gearSpriteRenderer.color = (currentState == State.Traction || currentState == State.Attract) ? cutEdgeColor : normalEdgeColor; } } - // 从Sprite的PhysicsShape获取边缘点,构成闭环路径 private void LoadEdgePointsFromSprite() { - List originalPoints = new List(); + edgePoints = new List(); if (targetSpriteRenderer == null) { Debug.LogError("targetSpriteRenderer 为空"); @@ -161,7 +124,6 @@ public class GearFollower : MonoBehaviour return; } - // 计算形状的中心点 Vector2 center = Vector2.zero; foreach (Vector2 point in shapePoints) { @@ -169,191 +131,129 @@ public class GearFollower : MonoBehaviour } center /= shapePoints.Count; - // 转换为世界坐标并应用放大 - originalPoints = shapePoints - .Select(p => { + edgePoints = shapePoints + .Select(p => + { Vector2 dirFromCenter = p - center; Vector2 scaledPoint = center + dirFromCenter * edgeScaleFactor; return (Vector2)targetSpriteRenderer.transform.TransformPoint(scaledPoint); }) .ToList(); - // 确保首尾连通 - if (originalPoints[0] != originalPoints[originalPoints.Count - 1]) + if (edgePoints[0] != edgePoints[edgePoints.Count - 1]) { - originalPoints.Add(originalPoints[0]); - } - - // 生成插值点 - edgePoints = new List(); - for (int i = 0; i < originalPoints.Count - 1; i++) - { - Vector2 start = originalPoints[i]; - Vector2 end = originalPoints[i + 1]; - - // 添加起始点 - edgePoints.Add(start); - - // 在两点之间插入插值点 - for (int j = 1; j <= interpolationPoints; j++) - { - float t = j / (float)(interpolationPoints + 1); - Vector2 interpolatedPoint = Vector2.Lerp(start, end, t); - edgePoints.Add(interpolatedPoint); - } - } - - // 添加最后一个点 - edgePoints.Add(originalPoints[originalPoints.Count - 1]); - - // 初始化切割状态数组 - cutStates = new List(new bool[edgePoints.Count]); - cutTimes = new List(new float[edgePoints.Count]); - - // 更新路径渲染器 - UpdatePathRenderer(); - } - - private void UpdatePathRenderer() - { - if (pathRenderer != null) - { - pathRenderer.positionCount = edgePoints.Count; - for (int i = 0; i < edgePoints.Count; i++) - { - pathRenderer.SetPosition(i, new Vector3(edgePoints[i].x, edgePoints[i].y, 0)); - } + edgePoints.Add(edgePoints[0]); } } - // 跟随模式逻辑 private void UpdateFollowState(Vector2 mousePos) { - // 使用平滑移动 - transform.position = Vector2.SmoothDamp(transform.position, mousePos, ref currentVelocity, smoothTime); + transform.position = mousePos; - // 检测距离最近边缘点是否在snapDistance内,进入牵引 int nearestIndex = FindNearestEdgePointIndex(mousePos, out float dist); if (dist < snapDistance) { currentEdgeIndex = nearestIndex; - currentState = State.Traction; - currentPathProgress = 0f; - - // 立即吸附到最近的边缘点 - transform.position = edgePoints[currentEdgeIndex]; - + currentState = State.Attract; if (gearSpriteRenderer != null) - { gearSpriteRenderer.sortingOrder = 1; - } - pathRenderer.enabled = true; } } - // 牵引模式逻辑 - private void UpdateTractionState(Vector2 mousePos) + private void UpdateAttractState(Vector2 mousePos) { - Vector2 gearPos = (Vector2)transform.position; + Vector2 closestPoint = Vector2.zero; + float closestDist = float.MaxValue; + int closestSegmentStartIndex = 0; - // 计算鼠标到齿轮的距离 - float distToGear = Vector2.Distance(mousePos, gearPos); - - // 计算鼠标到图片中心的距离 - float distToCenter = Vector2.Distance(mousePos, imageCenter); - - // 如果鼠标在图片内部(距离中心小于半径),或者距离齿轮太近,则不脱离吸附 - if (distToGear > detachDistance && distToCenter > imageRadius) + for (int i = 0; i < edgePoints.Count - 1; i++) + { + Vector2 a = edgePoints[i]; + Vector2 b = edgePoints[i + 1]; + Vector2 projected = ProjectPointOnSegment(mousePos, a, b); + float dist = Vector2.Distance(mousePos, projected); + + if (dist < closestDist) + { + closestDist = dist; + closestPoint = projected; + closestSegmentStartIndex = i; + } + } + + transform.position = closestPoint; + currentEdgeIndex = closestSegmentStartIndex; + + if (Vector2.Distance(mousePos, closestPoint) > detachDistance) { currentState = State.Follow; if (gearSpriteRenderer != null) - { gearSpriteRenderer.sortingOrder = 5; - } - pathRenderer.enabled = false; return; } - // 判断是否按住左键 - if (!Input.GetMouseButton(0)) + if (Input.GetMouseButton(0)) { - // 未按键,齿轮固定在当前位置 - return; + currentState = State.Traction; } - - // 沿路径移动 - MoveAlongPath(mousePos); } - // 沿路径移动的逻辑 - private void MoveAlongPath(Vector2 mousePos) + private void UpdateTractionState(Vector2 mousePos) { - // 计算鼠标到当前齿轮位置的距离 - float distToGear = Vector2.Distance(mousePos, transform.position); - - // 获取当前段落的起点和终点 - Vector2 startPoint = edgePoints[currentEdgeIndex]; - Vector2 endPoint = edgePoints[(currentEdgeIndex + 1) % edgePoints.Count]; - - // 计算鼠标到当前段落两端点的距离 - float distToStart = Vector2.Distance(mousePos, startPoint); - float distToEnd = Vector2.Distance(mousePos, endPoint); - - // 计算移动方向 - float moveDirection = 0f; - - // 获取鼠标相对于当前段落的向量 - Vector2 mouseToStart = mousePos - startPoint; - Vector2 segmentVector = endPoint - startPoint; - - // 计算叉积来判断方向 - float crossProduct = mouseToStart.x * segmentVector.y - mouseToStart.y * segmentVector.x; - - // 根据叉积的符号决定移动方向 - moveDirection = crossProduct > 0 ? -1f : 1f; - - // 计算移动速度 - float moveSpeed = tractionSpeed * (cutStates[currentEdgeIndex] ? speedMultiplier : 1f); - - // 使用固定速度更新移动 - float maxProgressChange = moveSpeed * Time.deltaTime; - float targetProgress = currentPathProgress + moveDirection * maxProgressChange; - - // 处理段落切换 - if (targetProgress >= 1f) + if (Vector2.Distance(mousePos, transform.position) > detachDistance) { - currentEdgeIndex = (currentEdgeIndex + 1) % edgePoints.Count; - targetProgress = 0f; - currentCutTime = 0f; // 重置切割时间 + currentState = State.Follow; + if (gearSpriteRenderer != null) + gearSpriteRenderer.sortingOrder = 5; + return; } - else if (targetProgress <= 0f) + + if (Input.GetMouseButton(0)) { - // 修改逆时针移动的处理逻辑 - currentEdgeIndex = (currentEdgeIndex - 1 + edgePoints.Count) % edgePoints.Count; - targetProgress = 1f; - currentCutTime = 0f; // 重置切割时间 - - // 确保不会出现负值 - if (currentEdgeIndex < 0) + MoveAlongEdge(mousePos); + } + } + + private void MoveAlongEdge(Vector2 mousePos) + { + float closestDist = float.MaxValue; + Vector2 closestPoint = Vector2.zero; + int closestSegmentStartIndex = 0; + + for (int i = 0; i < edgePoints.Count - 1; i++) + { + Vector2 a = edgePoints[i]; + Vector2 b = edgePoints[i + 1]; + + Vector2 projected = ProjectPointOnSegment(mousePos, a, b); + float dist = Vector2.Distance(mousePos, projected); + + if (dist < closestDist) { - currentEdgeIndex = edgePoints.Count - 1; + closestDist = dist; + closestPoint = projected; + closestSegmentStartIndex = i; } } - // 更新进度 - currentPathProgress = targetProgress; + float stopThreshold = 0.05f; + if (Vector2.Distance(transform.position, closestPoint) < stopThreshold) + { + return; + } - // 计算目标位置 - startPoint = edgePoints[currentEdgeIndex]; - endPoint = edgePoints[(currentEdgeIndex + 1) % edgePoints.Count]; - Vector2 targetPos = Vector2.Lerp(startPoint, endPoint, currentPathProgress); + transform.position = Vector2.MoveTowards(transform.position, closestPoint, tractionSpeed * Time.deltaTime); + currentEdgeIndex = closestSegmentStartIndex; - // 使用平滑移动 - transform.position = Vector2.SmoothDamp(transform.position, targetPos, ref currentVelocity, edgeSmoothTime); + // 标记当前线段已被切割 + if (!cutSegments[currentEdgeIndex]) + { + cutSegments[currentEdgeIndex] = true; + Debug.Log($"切割了线段 {currentEdgeIndex} ({edgePoints[currentEdgeIndex]}->{edgePoints[currentEdgeIndex + 1]})"); + } } - // 找到距离pos最近的边缘点索引和距离 private int FindNearestEdgePointIndex(Vector2 pos, out float minDist) { int nearestIndex = 0; @@ -371,19 +271,50 @@ public class GearFollower : MonoBehaviour return nearestIndex; } - // 更新路径显示 - private void UpdatePathDisplay() + private Vector2 ProjectPointOnSegment(Vector2 point, Vector2 a, Vector2 b) { - if (pathRenderer != null && pathRenderer.enabled) + Vector2 ab = b - a; + float abLengthSquared = ab.sqrMagnitude; + if (abLengthSquared == 0f) return a; + + float t = Vector2.Dot(point - a, ab) / abLengthSquared; + t = Mathf.Clamp01(t); + return a + t * ab; + } + + private void UpdateCutLineRenderer() + { + // 统计所有已切割线段点数 = 2*切割线段数(start和end) + int count = cutSegments.Count(cut => cut); + if (count == 0) { - for (int i = 0; i < edgePoints.Count; i++) + cutLineRenderer.positionCount = 0; + return; + } + + // 每个切割线段2个点 + cutLineRenderer.positionCount = count * 2; + + int index = 0; + for (int i = 0; i < cutSegments.Length; i++) + { + if (cutSegments[i]) { - Color segmentColor = cutStates[i] ? cutPathColor : pathColor; - pathRenderer.startColor = segmentColor; - pathRenderer.endColor = segmentColor; + cutLineRenderer.SetPosition(index, edgePoints[i]); + cutLineRenderer.SetPosition(index + 1, edgePoints[i + 1]); + index += 2; } } } + private void CheckAllSegmentsCut() + { + if (cutSegments == null) return; + if (System.Array.TrueForAll(cutSegments, cut => cut)) + { + Debug.Log("所有边缘线段都已经切割完成!"); + enabled = false; + } + } }