基本交互和视觉效果确定
This commit is contained in:
@@ -0,0 +1,198 @@
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class CuttingSystem : MonoBehaviour
|
||||
{
|
||||
[Header("切割系统参数")]
|
||||
public float snapDistance = 0.3f;
|
||||
public float detachDistance = 1.0f;
|
||||
public float directionSwitchCooldown = 0.2f;
|
||||
private CutLineManager cutLineManager;
|
||||
public float tractionSpeed = 2f;
|
||||
|
||||
[Header("测试")]
|
||||
public SpriteRenderer TargetspriteRenderer;
|
||||
private GearController gearController;
|
||||
|
||||
private Camera mainCamera;
|
||||
private int currentEdgeIndex = 0;
|
||||
private int tractionDirection = 1;
|
||||
private float directionSwitchTimer = 0f;
|
||||
|
||||
private enum State { Follow, Traction }
|
||||
private State currentState = State.Follow;
|
||||
|
||||
private List<Vector2> edgePoints;
|
||||
private List<Vector2> originalEdgePoints;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
mainCamera = Camera.main;
|
||||
gearController = GetComponentInChildren<GearController>();
|
||||
cutLineManager = GetComponentInChildren<CutLineManager>();
|
||||
|
||||
edgePoints = new List<Vector2>();
|
||||
originalEdgePoints = new List<Vector2>();
|
||||
|
||||
if (TargetspriteRenderer != null)
|
||||
{
|
||||
InitializeCutting(TargetspriteRenderer);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("TargetspriteRenderer is null!");
|
||||
}
|
||||
}
|
||||
private void Update()
|
||||
{
|
||||
UpdateCutting();
|
||||
}
|
||||
|
||||
public void InitializeCutting(SpriteRenderer targetSprite, float edgePointsScale = 1.2f)
|
||||
{
|
||||
if (targetSprite == null) return;
|
||||
LoadEdgePointsFromSprite(targetSprite, edgePointsScale);
|
||||
Debug.Log($"InitializeCutting: edgePoints count = {edgePoints.Count}");
|
||||
}
|
||||
|
||||
public void UpdateCutting()
|
||||
{
|
||||
Vector2 mouseWorldPos = mainCamera.ScreenToWorldPoint(Input.mousePosition);
|
||||
|
||||
if (Input.GetMouseButton(0))
|
||||
{
|
||||
gearController.SetRotation(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
gearController.SetRotation(false);
|
||||
}
|
||||
|
||||
switch (currentState)
|
||||
{
|
||||
case State.Follow:
|
||||
UpdateFollowState(mouseWorldPos);
|
||||
break;
|
||||
case State.Traction:
|
||||
UpdateTractionState(mouseWorldPos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadEdgePointsFromSprite(SpriteRenderer targetSprite, float edgePointsScale)
|
||||
{
|
||||
var shapePoints = CuttingUtils.GetSpritePhysicsShapePoints(targetSprite);
|
||||
if (shapePoints == null) return;
|
||||
|
||||
var (scaledPoints, originalPoints) = CuttingUtils.ProcessEdgePoints(shapePoints, targetSprite, edgePointsScale);
|
||||
if (scaledPoints == null) return;
|
||||
|
||||
edgePoints = scaledPoints;
|
||||
originalEdgePoints = originalPoints;
|
||||
Debug.Log($"LoadEdgePointsFromSprite: edgePoints count = {edgePoints.Count}");
|
||||
}
|
||||
|
||||
private void UpdateFollowState(Vector2 mousePos)
|
||||
{
|
||||
gearController.transform.position = mousePos;
|
||||
|
||||
int nearestIndex = CuttingUtils.FindNearestEdgePointIndex(mousePos, edgePoints, out float dist);
|
||||
Debug.Log($"Distance to nearest point: {dist}, Snap distance: {snapDistance}");
|
||||
|
||||
if (dist < snapDistance)
|
||||
{
|
||||
currentEdgeIndex = nearestIndex;
|
||||
|
||||
Vector2 prev = edgePoints[CuttingUtils.WrapIndex(currentEdgeIndex - 1, edgePoints.Count)];
|
||||
Vector2 next = edgePoints[CuttingUtils.WrapIndex(currentEdgeIndex + 1, edgePoints.Count)];
|
||||
|
||||
float distToPrev = Vector2.Distance(mousePos, prev);
|
||||
float distToNext = Vector2.Distance(mousePos, next);
|
||||
|
||||
tractionDirection = (distToNext < distToPrev) ? 1 : -1;
|
||||
|
||||
gearController.transform.position = edgePoints[currentEdgeIndex];
|
||||
currentState = State.Traction;
|
||||
Debug.Log("Switched to Traction state");
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateTractionState(Vector2 mousePos)
|
||||
{
|
||||
Vector2 gearPos = transform.position;
|
||||
|
||||
if (Vector2.Distance(mousePos, gearPos) > detachDistance)
|
||||
{
|
||||
currentState = State.Follow;
|
||||
cutLineManager.EndCutting();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Input.GetMouseButton(0))
|
||||
{
|
||||
cutLineManager.EndCutting();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cutLineManager.IsCutting)
|
||||
{
|
||||
cutLineManager.StartCutting();
|
||||
}
|
||||
|
||||
int nextIndex = CuttingUtils.WrapIndex(currentEdgeIndex + tractionDirection, edgePoints.Count);
|
||||
Vector2 from = edgePoints[currentEdgeIndex];
|
||||
Vector2 to = edgePoints[nextIndex];
|
||||
|
||||
Vector2 forward = (to - from).normalized;
|
||||
Vector2 toMouse = (mousePos - from).normalized;
|
||||
float angle = Vector2.SignedAngle(forward, toMouse);
|
||||
|
||||
if (Mathf.Abs(angle) > 120f)
|
||||
{
|
||||
directionSwitchTimer += Time.deltaTime;
|
||||
if (directionSwitchTimer > directionSwitchCooldown)
|
||||
{
|
||||
tractionDirection *= -1;
|
||||
directionSwitchTimer = 0f;
|
||||
|
||||
nextIndex = CuttingUtils.WrapIndex(currentEdgeIndex + tractionDirection, edgePoints.Count);
|
||||
from = edgePoints[currentEdgeIndex];
|
||||
to = edgePoints[nextIndex];
|
||||
forward = (to - from).normalized;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
directionSwitchTimer = 0f;
|
||||
}
|
||||
|
||||
Vector2 targetPoint = CuttingUtils.GetClosestPointOnSegment(from, to, mousePos);
|
||||
Vector2 moveDir = (targetPoint - gearPos);
|
||||
float distance = moveDir.magnitude;
|
||||
|
||||
float maxStep = tractionSpeed * Time.deltaTime;
|
||||
|
||||
if (distance <= maxStep)
|
||||
{
|
||||
gearController.transform.position = targetPoint;
|
||||
|
||||
if (Vector2.Distance(targetPoint, to) < 0.01f)
|
||||
{
|
||||
currentEdgeIndex = nextIndex;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gearController.transform.position += (Vector3)(moveDir.normalized * maxStep);
|
||||
}
|
||||
|
||||
Vector2 originalFrom = originalEdgePoints[currentEdgeIndex];
|
||||
Vector2 originalTo = originalEdgePoints[nextIndex];
|
||||
Vector2 originalTargetPoint = CuttingUtils.GetClosestPointOnSegment(originalFrom, originalTo, transform.position);
|
||||
|
||||
Vector3 noisyPoint = originalTargetPoint;
|
||||
noisyPoint.x += Random.Range(-cutLineManager.noiseAmount, cutLineManager.noiseAmount);
|
||||
noisyPoint.y += Random.Range(-cutLineManager.noiseAmount, cutLineManager.noiseAmount);
|
||||
cutLineManager.AddCutPoint(noisyPoint);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user