优化效果

This commit is contained in:
2025-05-17 17:28:45 +08:00
parent 1983ad53fc
commit 3ef8e4441d
5 changed files with 243 additions and 121 deletions
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using Shapes;
using UnityEngine;
public class GearFollower : MonoBehaviour
@@ -12,9 +13,12 @@ public class GearFollower : MonoBehaviour
[Header("切割轨迹")]
public LineRenderer cutLineRenderer;
public float cutLineWidth = 0.1f;
public float noiseAmount = 0.05f; // 毛刺偏移幅度
public float segmentDuration = 4f; // 线段持续时间
private List<Vector2> edgePoints;
private List<Vector2> originalEdgePoints; // 存储原始边缘点
private int currentEdgeIndex = 0;
@@ -31,6 +35,20 @@ public class GearFollower : MonoBehaviour
private float directionSwitchCooldown = 0.2f;
private float directionSwitchTimer = 0f;
private class TimedPoint
{
public Vector3 position;
public float timeAdded;
public TimedPoint(Vector3 pos, float time)
{
position = pos;
timeAdded = time;
}
}
private List<TimedPoint> timedCutPoints = new List<TimedPoint>();
public float cutLineDelay = 3f; // 延迟几秒才显示轨迹点
void Start()
{
mainCamera = Camera.main;
@@ -42,6 +60,7 @@ public class GearFollower : MonoBehaviour
cutLineRenderer.widthCurve = AnimationCurve.Constant(0, 1, cutLineWidth);
cutLineRenderer.material = new Material(Shader.Find("Sprites/Default"));
cutLineRenderer.numCapVertices = 0; // 线头不圆滑,显锐利
cutLineRenderer.sortingOrder = 1;
}
}
@@ -63,6 +82,7 @@ public class GearFollower : MonoBehaviour
UpdateTractionState(mouseWorldPos);
break;
}
UpdateCutLineRenderer();
}
private void LoadEdgePointsFromSprite()
@@ -127,7 +147,6 @@ public class GearFollower : MonoBehaviour
Debug.Log($"边缘点数量:{edgePoints.Count}");
}
private void UpdateFollowState(Vector2 mousePos)
{
transform.position = mousePos;
@@ -149,7 +168,6 @@ public class GearFollower : MonoBehaviour
currentState = State.Traction;
}
}
private void UpdateTractionState(Vector2 mousePos)
{
Vector2 gearPos = transform.position;
@@ -223,7 +241,7 @@ public class GearFollower : MonoBehaviour
Vector2 originalFrom = originalEdgePoints[currentEdgeIndex];
Vector2 originalTo = originalEdgePoints[nextIndex];
Vector2 originalTargetPoint = GetClosestPointOnSegment(originalFrom, originalTo, transform.position);
// 记录切割点(带噪声模拟毛糙)
Vector3 noisyPoint = originalTargetPoint;
noisyPoint.x += Random.Range(-noiseAmount, noiseAmount);
@@ -243,23 +261,48 @@ public class GearFollower : MonoBehaviour
private void AddCutPoint(Vector3 point)
{
if (cutLinePoints.Count == 0 || Vector3.Distance(cutLinePoints[cutLinePoints.Count - 1], point) > 0.01f)
if (timedCutPoints.Count == 0 || Vector3.Distance(timedCutPoints[timedCutPoints.Count - 1].position, point) > 0.05f)
{
cutLinePoints.Add(point);
if (cutLineRenderer != null)
timedCutPoints.Add(new TimedPoint(point, Time.time));
// 立即创建片段
if (timedCutPoints.Count >= 2)
{
cutLineRenderer.positionCount = cutLinePoints.Count;
cutLineRenderer.SetPositions(cutLinePoints.ToArray());
Vector3 prev = timedCutPoints[timedCutPoints.Count - 2].position;
Vector3 curr = timedCutPoints[timedCutPoints.Count - 1].position;
CreateSegment(prev, curr);
}
}
}
private void UpdateCutLineRenderer()
{
if (cutLineRenderer == null) return;
float currentTime = Time.time;
List<Vector3> visiblePoints = new List<Vector3>();
foreach (var timedPoint in timedCutPoints)
{
if (currentTime - timedPoint.timeAdded >= cutLineDelay)
{
visiblePoints.Add(timedPoint.position);
}
else
{
// 这里的点还没到延迟时间,不显示
}
}
cutLineRenderer.positionCount = visiblePoints.Count;
if (visiblePoints.Count > 0)
cutLineRenderer.SetPositions(visiblePoints.ToArray());
}
private void EndCutting()
{
isCutting = false;
// 这里可以添加切割结束后的淡出效果等
}
private int FindNearestEdgePointIndex(Vector2 pos, out float minDist)
{
int nearestIndex = 0;
@@ -291,4 +334,20 @@ public class GearFollower : MonoBehaviour
if (index >= edgePoints.Count - 1) return 0;
return index;
}
private void CreateSegment(Vector3 from, Vector3 to)
{
GameObject segObj = new GameObject("HeatLineSegment");
segObj.transform.parent = this.transform;
LineRenderer segLine = segObj.AddComponent<LineRenderer>();
segLine.positionCount = 2;
segLine.SetPosition(0, from);
segLine.SetPosition(1, to);
segLine.sortingOrder = 4;
segLine.material = new Material(Shader.Find("Sprites/Default"));
segLine.widthCurve = AnimationCurve.Constant(0, 1, cutLineWidth);
segLine.numCapVertices = 0;
var segmentController = segObj.AddComponent<HeatLineSegmentController>();
segmentController.duration = segmentDuration;
}
}
@@ -0,0 +1,51 @@
using UnityEngine;
using DG.Tweening;
public class HeatLineSegmentController : MonoBehaviour
{
private LineRenderer lineRenderer;
private Sequence sequence;
public float duration = 4f; // 整个冷却淡出时间
public Color hotColor = Color.red;
public Color coldColor = Color.black;
void Awake()
{
lineRenderer = GetComponent<LineRenderer>();
if (lineRenderer == null)
{
Debug.LogError("HeatLineSegmentController需要LineRenderer组件");
}
lineRenderer.startColor = lineRenderer.endColor = hotColor;
}
void Start()
{
// 创建颜色渐变序列
sequence = DOTween.Sequence();
// 颜色从热色到冷色
sequence.Append(DOTween.To(() => lineRenderer.startColor, x => {
lineRenderer.startColor = x;
lineRenderer.endColor = x;
}, coldColor, duration * 0.7f).SetEase(Ease.InOutQuad));
// 淡出效果
sequence.Append(DOTween.To(() => lineRenderer.startColor.a, x => {
Color c = lineRenderer.startColor;
c.a = x;
lineRenderer.startColor = c;
lineRenderer.endColor = c;
}, 0f, duration * 0.3f).SetEase(Ease.InQuad));
// 完成后销毁对象
sequence.OnComplete(() => Destroy(gameObject));
}
void OnDestroy()
{
// 清理DOTween序列
sequence?.Kill();
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6a522756b1d3f1640981d73f044ab755
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: