切割接入
This commit is contained in:
@@ -5,6 +5,7 @@ using AibisDream.Framework;
|
||||
using AibisDream.Kit;
|
||||
using AibisDream.Utility;
|
||||
using DG.Tweening;
|
||||
using JetBrains.Annotations;
|
||||
using Newtonsoft.Json;
|
||||
using UnityEngine;
|
||||
|
||||
@@ -25,6 +26,9 @@ namespace AibisDream.FixSystem
|
||||
|
||||
private SpriteRenderer _targetSpriteRenderer; // 目标的 SpriteRenderer
|
||||
|
||||
private SpriteRenderer _cutSpriteRenderer;
|
||||
|
||||
|
||||
private CutLine _cutLine;
|
||||
|
||||
#endregion
|
||||
@@ -47,7 +51,10 @@ namespace AibisDream.FixSystem
|
||||
_bodyModuleSystem = transform.parent.parent.GetComponent<BodyModuleSystem>();
|
||||
|
||||
_targetSpriteRenderer = transform.Find("Module Pic").GetComponent<SpriteRenderer>();
|
||||
_originalMaterial = _targetSpriteRenderer.GetComponent<SpriteRenderer>().material;
|
||||
_originalMaterial = _targetSpriteRenderer.GetComponent<SpriteRenderer>().material;
|
||||
|
||||
_cutSpriteRenderer = transform.Find("Cut Pic").GetComponent<SpriteRenderer>();
|
||||
|
||||
_highlightMaterial = Resources.Load<Material>("Materials/HighlightMaterial");
|
||||
_alarmMaterial = Resources.Load<Material>("Materials/AlarmMaterial");
|
||||
}
|
||||
@@ -117,6 +124,19 @@ namespace AibisDream.FixSystem
|
||||
return _targetSpriteRenderer;
|
||||
}
|
||||
|
||||
public void OnCuttingDown()
|
||||
{
|
||||
_bodyModuleSystem.RemoveModule(this);
|
||||
|
||||
DialogController.Instance?.StartDialogNode($"{data.moduleName}CutDown");
|
||||
EnumEventSystem.Global.Send(EventEnum.CutEnd);
|
||||
Destroy(gameObject);
|
||||
}
|
||||
|
||||
public SpriteRenderer GetCutSpriteRenderer()
|
||||
{
|
||||
return _cutSpriteRenderer;
|
||||
}
|
||||
|
||||
// public void EnableCut()
|
||||
// {
|
||||
|
||||
@@ -10,13 +10,13 @@ namespace AibisDream
|
||||
private static BodyModuleSystem BodyModuleSystem => FixSystemCenter.SystemDic.Get<BodyModuleSystem>();
|
||||
private static PunchTapeSystem PunchTapeSystem => FixSystemCenter.SystemDic.Get<PunchTapeSystem>();
|
||||
|
||||
// [YarnCommand("enable_cut")]
|
||||
// public static void EnableCut(string moduleName)
|
||||
// {
|
||||
// Reset_Plug();
|
||||
// var cutModule = BodyModuleSystem.FindBodyModuleByName(moduleName);
|
||||
// cutModule.EnableCut();
|
||||
// }
|
||||
[YarnCommand("enable_cut")]
|
||||
public static void EnableCut(string moduleName)
|
||||
{
|
||||
Reset_Plug();
|
||||
var cutModule = BodyModuleSystem.FindBodyModuleByName(moduleName);
|
||||
//cutModule.EnableCut();
|
||||
}
|
||||
[YarnCommand("Reset_Plug")]
|
||||
public static void Reset_Plug()
|
||||
{
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
using UnityEngine;
|
||||
using AibisDream;
|
||||
using AibisDream.FixSystem;
|
||||
using Cinemachine;
|
||||
using AibisDream.Framework;
|
||||
using AibisDream.Kit;
|
||||
using UnityEditor.Localization.Plugins.XLIFF.V12;
|
||||
|
||||
namespace AibisDream
|
||||
{
|
||||
public class CuttingManager : MonoBehaviour
|
||||
{
|
||||
[Header("切割组件")]
|
||||
public GameObject gearFollowerPrefab;
|
||||
private GearFollower gearFollower;
|
||||
private bool isCuttingMode = false;
|
||||
private BodyModule _targetModule;
|
||||
private SpriteRenderer _targetSpriteRenderer;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
// 注册
|
||||
FixSystemCenter.SystemDic.Register(this);
|
||||
var virtualCam1 = transform.Find("Cut Emo Camera").GetComponent<ICinemachineCamera>();
|
||||
var virtualCam2 = transform.Find("Cut Memory Camera").GetComponent<ICinemachineCamera>();
|
||||
var virtualCam3 = transform.Find("Cut Logic Camera").GetComponent<ICinemachineCamera>();
|
||||
var virtualCam4 = transform.Find("Cut Emo Deep Camera").GetComponent<ICinemachineCamera>();
|
||||
var virtualCam5 = transform.Find("Cut Memory Deep Camera").GetComponent<ICinemachineCamera>();
|
||||
var virtualCam6 = transform.Find("Cut Logic Deep Camera").GetComponent<ICinemachineCamera>();
|
||||
CameraKit.Instance.RegisterCamera(CameraEnum.CutEmo, virtualCam1);
|
||||
CameraKit.Instance.RegisterCamera(CameraEnum.CutMemory, virtualCam2);
|
||||
CameraKit.Instance.RegisterCamera(CameraEnum.CutLogic, virtualCam3);
|
||||
CameraKit.Instance.RegisterCamera(CameraEnum.CutEmoDeep, virtualCam4);
|
||||
CameraKit.Instance.RegisterCamera(CameraEnum.CutMemoryDeep, virtualCam5);
|
||||
CameraKit.Instance.RegisterCamera(CameraEnum.CutLogicDeep, virtualCam6);
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (isCuttingMode && gearFollower != null)
|
||||
{
|
||||
gearFollower.GearUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
public void StartCutting(BodyModule targetModule)
|
||||
{
|
||||
// 检查参数
|
||||
if (targetModule == null)
|
||||
{
|
||||
Debug.LogError("targetModule 为空");
|
||||
return;
|
||||
}
|
||||
|
||||
// 保存目标模块
|
||||
_targetModule = targetModule;
|
||||
|
||||
// 获取目标精灵渲染器
|
||||
_targetSpriteRenderer = targetModule.GetCutSpriteRenderer();
|
||||
if (_targetSpriteRenderer == null)
|
||||
{
|
||||
Debug.LogError("targetSprite 为空");
|
||||
return;
|
||||
}
|
||||
|
||||
// 停止之前的切割
|
||||
StopCutting();
|
||||
|
||||
// 设置切割模式
|
||||
isCuttingMode = true;
|
||||
|
||||
// 创建GearFollower
|
||||
Vector3 SpawnPosition = new Vector3(Screen.width / 2f, Screen.height / 4f, 0);
|
||||
GameObject gearFollowerObj = Instantiate(gearFollowerPrefab, SpawnPosition, Quaternion.identity);
|
||||
gearFollower = gearFollowerObj.GetComponent<GearFollower>();
|
||||
gearFollower.Init(_targetSpriteRenderer);
|
||||
}
|
||||
|
||||
public void OnCutComplete()
|
||||
{
|
||||
isCuttingMode = false;
|
||||
if (gearFollower != null)
|
||||
{
|
||||
gearFollower.FinishCutting();
|
||||
}
|
||||
}
|
||||
public void UpdateModule()
|
||||
{
|
||||
if (_targetModule != null)
|
||||
{
|
||||
_targetModule.OnCuttingDown();
|
||||
}
|
||||
}
|
||||
|
||||
public void StopCutting()
|
||||
{
|
||||
isCuttingMode = false;
|
||||
if (gearFollower != null)
|
||||
{
|
||||
Destroy(gearFollower.gameObject);
|
||||
gearFollower = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fe673cb153d7fdf428d58d3261c48863
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -4,12 +4,14 @@ using UnityEngine;
|
||||
using UnityEngine.Rendering.Universal;
|
||||
using UnityEngine.VFX;
|
||||
using DG.Tweening;
|
||||
using AibisDream.FixSystem;
|
||||
using AibisDream; // 添加OpenSystem的命名空间
|
||||
|
||||
public class GearFollower : MonoBehaviour
|
||||
{
|
||||
[Header("参数")]
|
||||
public SpriteRenderer targetSpriteRenderer;
|
||||
public float snapDistance = 0.3f;
|
||||
public float snapDistance = 1.0f;
|
||||
public float detachDistance = 1.0f;
|
||||
public float tractionSpeed = 2f;
|
||||
public float edgePointsScale = 1.2f; // 边缘点缩放倍率
|
||||
@@ -42,7 +44,7 @@ public class GearFollower : MonoBehaviour
|
||||
public float scaleUpDuration = 1f; // 放大动画持续时间
|
||||
public float fadeOutDelay = 1f; // 淡出前的延迟时间
|
||||
public AudioClip cutCompleteSound; // 切割完成音效
|
||||
|
||||
|
||||
private float totalEdgeLength = 0f; // 总边缘长度
|
||||
private float cutLength = 0f; // 已切割长度
|
||||
private bool isCutComplete = false;
|
||||
@@ -86,6 +88,16 @@ public class GearFollower : MonoBehaviour
|
||||
|
||||
void Start()
|
||||
{
|
||||
}
|
||||
public void Init(SpriteRenderer targetSpriteRenderer)
|
||||
{
|
||||
SpriteRenderer gearRenderer = GetComponent<SpriteRenderer>();
|
||||
if (gearRenderer != null)
|
||||
{
|
||||
gearRenderer.color = new Color(1, 1, 1, 1);
|
||||
}
|
||||
this.targetSpriteRenderer = null;
|
||||
this.targetSpriteRenderer = targetSpriteRenderer;
|
||||
mainCamera = Camera.main;
|
||||
LoadEdgePointsFromSprite();
|
||||
CalculateTotalEdgeLength();
|
||||
@@ -118,7 +130,24 @@ public class GearFollower : MonoBehaviour
|
||||
}
|
||||
void Update()
|
||||
{
|
||||
Vector2 mouseWorldPos = mainCamera.ScreenToWorldPoint(Input.mousePosition);
|
||||
|
||||
}
|
||||
public void GearUpdate()
|
||||
{
|
||||
// 获取鼠标在屏幕上的位置
|
||||
Vector3 mouseScreenPos = Input.mousePosition;
|
||||
// 将屏幕坐标转换为世界坐标
|
||||
Vector3 mouseWorldPos = mainCamera.ScreenToWorldPoint(new Vector3(mouseScreenPos.x, mouseScreenPos.y, -mainCamera.transform.position.z));
|
||||
mouseWorldPos.z = 0; // 确保z坐标为0
|
||||
|
||||
Debug.Log($"鼠标屏幕坐标: {mouseScreenPos}");
|
||||
Debug.Log($"鼠标世界坐标: {mouseWorldPos}");
|
||||
Debug.Log($"齿轮当前位置: {transform.position}");
|
||||
if (targetSpriteRenderer != null)
|
||||
{
|
||||
Debug.Log($"目标精灵位置: {targetSpriteRenderer.transform.position}");
|
||||
Debug.Log($"目标精灵边界: {targetSpriteRenderer.bounds}");
|
||||
}
|
||||
|
||||
if (Input.GetMouseButton(0))
|
||||
{
|
||||
@@ -181,7 +210,7 @@ public class GearFollower : MonoBehaviour
|
||||
{
|
||||
fadeOutTimer += Time.deltaTime;
|
||||
float alpha = 1f - (fadeOutTimer / fadeOutDuration);
|
||||
|
||||
|
||||
if (targetSpriteRenderer != null)
|
||||
{
|
||||
Color color = targetSpriteRenderer.color;
|
||||
@@ -220,6 +249,7 @@ public class GearFollower : MonoBehaviour
|
||||
Debug.LogError("targetSpriteRenderer 为空");
|
||||
return;
|
||||
}
|
||||
|
||||
List<Vector2> shapePoints = new List<Vector2>();
|
||||
targetSpriteRenderer.sprite.GetPhysicsShape(0, shapePoints);
|
||||
|
||||
@@ -228,33 +258,70 @@ public class GearFollower : MonoBehaviour
|
||||
Debug.LogError("目标Sprite没有物理形状点");
|
||||
return;
|
||||
}
|
||||
Debug.Log($"原始形状点数量: {shapePoints.Count}");
|
||||
float desiredSegmentLength = 0.1f;
|
||||
|
||||
edgePoints.Clear();
|
||||
originalEdgePoints.Clear();
|
||||
Vector2 center = Vector2.zero;
|
||||
foreach (Vector2 point in shapePoints)
|
||||
{
|
||||
center += point;
|
||||
}
|
||||
center /= shapePoints.Count;
|
||||
|
||||
// 获取精灵的世界坐标
|
||||
Vector3 spriteWorldPos = targetSpriteRenderer.transform.position;
|
||||
Debug.Log($"精灵世界坐标: {spriteWorldPos}");
|
||||
|
||||
// 计算精灵的局部边界
|
||||
Bounds localBounds = targetSpriteRenderer.bounds;
|
||||
Vector3 localCenter = localBounds.center;
|
||||
Vector3 localSize = localBounds.size;
|
||||
|
||||
// 计算缩放后的边界
|
||||
float maxScale = Mathf.Max(localSize.x, localSize.y) * edgePointsScale;
|
||||
float minScale = Mathf.Min(localSize.x, localSize.y) * edgePointsScale;
|
||||
|
||||
Debug.Log($"精灵局部边界: 中心={localCenter}, 大小={localSize}");
|
||||
Debug.Log($"缩放后边界: 最大={maxScale}, 最小={minScale}");
|
||||
|
||||
for (int i = 0; i < shapePoints.Count; i++)
|
||||
{
|
||||
Vector2 p1 = targetSpriteRenderer.transform.TransformPoint(shapePoints[i]);
|
||||
Vector2 p2 = targetSpriteRenderer.transform.TransformPoint(shapePoints[(i + 1) % shapePoints.Count]);
|
||||
// 将局部坐标转换为世界坐标
|
||||
Vector3 localPoint1 = shapePoints[i];
|
||||
Vector3 localPoint2 = shapePoints[(i + 1) % shapePoints.Count];
|
||||
|
||||
Vector2 scaledP1 = center + (p1 - center) * edgePointsScale;
|
||||
Vector2 scaledP2 = center + (p2 - center) * edgePointsScale;
|
||||
// 转换为世界坐标
|
||||
Vector3 worldPoint1 = targetSpriteRenderer.transform.TransformPoint(localPoint1);
|
||||
Vector3 worldPoint2 = targetSpriteRenderer.transform.TransformPoint(localPoint2);
|
||||
|
||||
float segmentLength = Vector2.Distance(scaledP1, scaledP2);
|
||||
// 确保坐标在合理范围内
|
||||
worldPoint1 = ClampPosition(worldPoint1, spriteWorldPos, maxScale);
|
||||
worldPoint2 = ClampPosition(worldPoint2, spriteWorldPos, maxScale);
|
||||
|
||||
Debug.Log($"点 {i} 局部坐标: {localPoint1} -> 世界坐标: {worldPoint1}");
|
||||
|
||||
// 计算相对于精灵中心点的缩放
|
||||
Vector3 scaledPoint1 = spriteWorldPos + (worldPoint1 - spriteWorldPos) * edgePointsScale;
|
||||
Vector3 scaledPoint2 = spriteWorldPos + (worldPoint2 - spriteWorldPos) * edgePointsScale;
|
||||
|
||||
// 确保缩放后的点也在合理范围内
|
||||
scaledPoint1 = ClampPosition(scaledPoint1, spriteWorldPos, maxScale);
|
||||
scaledPoint2 = ClampPosition(scaledPoint2, spriteWorldPos, maxScale);
|
||||
|
||||
Debug.Log($"点 {i} 缩放后世界坐标: {scaledPoint1}");
|
||||
|
||||
float segmentLength = Vector3.Distance(scaledPoint1, scaledPoint2);
|
||||
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);
|
||||
edgePoints.Add(interpolated);
|
||||
originalEdgePoints.Add(originalInterpolated);
|
||||
Vector3 interpolated = Vector3.Lerp(scaledPoint1, scaledPoint2, t);
|
||||
Vector3 originalInterpolated = Vector3.Lerp(worldPoint1, worldPoint2, t);
|
||||
|
||||
// 确保插值点也在合理范围内
|
||||
interpolated = ClampPosition(interpolated, spriteWorldPos, maxScale);
|
||||
originalInterpolated = ClampPosition(originalInterpolated, spriteWorldPos, maxScale);
|
||||
|
||||
// 存储为Vector2,但保持世界坐标
|
||||
edgePoints.Add(new Vector2(interpolated.x, interpolated.y));
|
||||
originalEdgePoints.Add(new Vector2(originalInterpolated.x, originalInterpolated.y));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,22 +330,48 @@ public class GearFollower : MonoBehaviour
|
||||
edgePoints.Add(edgePoints[0]);
|
||||
originalEdgePoints.Add(originalEdgePoints[0]);
|
||||
}
|
||||
|
||||
Debug.Log($"生成的边缘点数量: {edgePoints.Count}");
|
||||
Debug.Log($"第一个边缘点世界坐标: {edgePoints[0]}");
|
||||
Debug.Log($"最后一个边缘点世界坐标: {edgePoints[edgePoints.Count - 1]}");
|
||||
}
|
||||
|
||||
// 添加一个辅助方法来限制坐标范围
|
||||
private Vector3 ClampPosition(Vector3 position, Vector3 center, float maxDistance)
|
||||
{
|
||||
Vector3 offset = position - center;
|
||||
float distance = offset.magnitude;
|
||||
|
||||
if (distance > maxDistance)
|
||||
{
|
||||
offset = offset.normalized * maxDistance;
|
||||
position = center + offset;
|
||||
}
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
private void UpdateFollowState(Vector2 mousePos)
|
||||
{
|
||||
transform.position = mousePos;
|
||||
isInTractionMode = false;
|
||||
|
||||
int nearestIndex = FindNearestEdgePointIndex(mousePos, out float dist);
|
||||
Debug.Log($"最近边缘点索引: {nearestIndex}, 距离: {dist}");
|
||||
Debug.Log($"最近边缘点位置: {edgePoints[nearestIndex]}");
|
||||
Debug.Log($"当前snapDistance: {snapDistance}");
|
||||
|
||||
if (dist < snapDistance)
|
||||
{
|
||||
currentEdgeIndex = nearestIndex;
|
||||
|
||||
Vector2 prev = edgePoints[WrapIndex(currentEdgeIndex - 1)];
|
||||
Vector2 next = edgePoints[WrapIndex(currentEdgeIndex + 1)];
|
||||
Debug.Log($"前一个点: {prev}, 后一个点: {next}");
|
||||
|
||||
float distToPrev = Vector2.Distance(mousePos, prev);
|
||||
float distToNext = Vector2.Distance(mousePos, next);
|
||||
Debug.Log($"到前一个点距离: {distToPrev}, 到后一个点距离: {distToNext}");
|
||||
|
||||
tractionDirection = (distToNext < distToPrev) ? 1 : -1;
|
||||
|
||||
@@ -454,12 +547,14 @@ public class GearFollower : MonoBehaviour
|
||||
sparkVFX.Stop();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
private int FindNearestEdgePointIndex(Vector2 pos, out float minDist)
|
||||
{
|
||||
int nearestIndex = 0;
|
||||
minDist = float.MaxValue;
|
||||
|
||||
// 使用世界坐标进行距离计算
|
||||
for (int i = 0; i < edgePoints.Count; i++)
|
||||
{
|
||||
float dist = Vector2.Distance(pos, edgePoints[i]);
|
||||
@@ -509,22 +604,29 @@ public class GearFollower : MonoBehaviour
|
||||
{
|
||||
totalEdgeLength += Vector2.Distance(edgePoints[i], edgePoints[i + 1]);
|
||||
}
|
||||
Debug.Log($"计算总边缘长度: {totalEdgeLength}");
|
||||
}
|
||||
|
||||
private void UpdateCutProgress(Vector2 from, Vector2 to)
|
||||
{
|
||||
cutLength += Vector2.Distance(from, to);
|
||||
float progress = cutLength / totalEdgeLength;
|
||||
|
||||
// 计算当前段的切割长度
|
||||
float segmentLength = Vector2.Distance(from, to);
|
||||
cutLength += segmentLength;
|
||||
|
||||
// 记录已切割的边缘点
|
||||
cutEdgeIndices.Add(currentEdgeIndex);
|
||||
|
||||
|
||||
// 计算切割进度
|
||||
float progress = cutLength / totalEdgeLength;
|
||||
Debug.Log($"当前切割长度: {cutLength}, 总长度: {totalEdgeLength}, 进度: {progress * 100}%");
|
||||
|
||||
// 检查是否满足切割完成条件
|
||||
if (!isCutComplete && progress >= cutCompletionThreshold && progress >= minCutLength)
|
||||
if (!isCutComplete && progress >= cutCompletionThreshold)
|
||||
{
|
||||
// 检查是否形成了连续的切割路径
|
||||
bool hasContinuousCut = CheckContinuousCut();
|
||||
|
||||
Debug.Log($"连续切割检查: {hasContinuousCut}, 已切割点数: {cutEdgeIndices.Count}, 总点数: {edgePoints.Count}");
|
||||
|
||||
if (hasContinuousCut)
|
||||
{
|
||||
isCutComplete = true;
|
||||
@@ -544,32 +646,64 @@ public class GearFollower : MonoBehaviour
|
||||
// 检查是否有连续的切割点
|
||||
int continuousCount = 1;
|
||||
int maxContinuousCount = 1;
|
||||
int totalPoints = edgePoints.Count;
|
||||
|
||||
for (int i = 1; i < sortedIndices.Count; i++)
|
||||
// 检查所有可能的连续段
|
||||
for (int startIndex = 0; startIndex < sortedIndices.Count; startIndex++)
|
||||
{
|
||||
if (sortedIndices[i] == sortedIndices[i - 1] + 1)
|
||||
continuousCount = 1;
|
||||
int currentIndex = sortedIndices[startIndex];
|
||||
|
||||
// 向前检查
|
||||
for (int i = 1; i < sortedIndices.Count; i++)
|
||||
{
|
||||
continuousCount++;
|
||||
maxContinuousCount = Mathf.Max(maxContinuousCount, continuousCount);
|
||||
int nextIndex = (currentIndex + i) % totalPoints;
|
||||
if (sortedIndices.Contains(nextIndex))
|
||||
{
|
||||
continuousCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
// 向后检查
|
||||
for (int i = 1; i < sortedIndices.Count; i++)
|
||||
{
|
||||
continuousCount = 1;
|
||||
int prevIndex = (currentIndex - i + totalPoints) % totalPoints;
|
||||
if (sortedIndices.Contains(prevIndex))
|
||||
{
|
||||
continuousCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
maxContinuousCount = Mathf.Max(maxContinuousCount, continuousCount);
|
||||
}
|
||||
|
||||
// 如果连续切割点的数量超过总点数的50%,认为形成了有效的切割路径
|
||||
return maxContinuousCount >= edgePoints.Count * 0.5f;
|
||||
// 计算连续切割点的比例
|
||||
float continuousRatio = (float)maxContinuousCount / totalPoints;
|
||||
Debug.Log($"最大连续切割点数: {maxContinuousCount}, 总点数: {totalPoints}, 比例: {continuousRatio * 100}%");
|
||||
|
||||
// 如果连续切割点的数量超过总点数的70%,认为形成了有效的切割路径
|
||||
return continuousRatio >= 0.7f;
|
||||
}
|
||||
|
||||
private void OnCutComplete()
|
||||
{
|
||||
// 停止切割状态
|
||||
isCutting = false;
|
||||
isInTractionMode = false;
|
||||
enabled = false;
|
||||
|
||||
// 清理特效
|
||||
var cuttingManager = FixSystemCenter.SystemDic.Get<CuttingManager>();
|
||||
if (cuttingManager != null)
|
||||
{
|
||||
cuttingManager.OnCutComplete();
|
||||
}
|
||||
}
|
||||
public void FinishCutting()
|
||||
{
|
||||
// 清理特效
|
||||
if (cutLight != null)
|
||||
{
|
||||
cutLight.enabled = false;
|
||||
@@ -582,47 +716,42 @@ public class GearFollower : MonoBehaviour
|
||||
{
|
||||
cutLineRenderer.positionCount = 0;
|
||||
}
|
||||
timedCutPoints.Clear();
|
||||
// 计算随机方向
|
||||
float randomAngle = Random.Range(-cutCompleteTiltAngle, cutCompleteTiltAngle);
|
||||
Vector2 randomOffset = Random.insideUnitCircle * cutCompleteOffset;
|
||||
|
||||
// 目标倾斜和位移
|
||||
if (targetSpriteRenderer != null)
|
||||
// 立即应用倾斜和位移
|
||||
targetSpriteRenderer.transform.rotation = Quaternion.Euler(0, 0, randomAngle);
|
||||
targetSpriteRenderer.transform.position = originalTargetPosition + (Vector3)randomOffset;
|
||||
|
||||
// 创建动画序列
|
||||
cutCompleteSequence = DOTween.Sequence();
|
||||
|
||||
// 等待一段时间后开始放大
|
||||
cutCompleteSequence.AppendInterval(cutCompleteDelay);
|
||||
cutCompleteSequence.Append(targetSpriteRenderer.transform.DOScale(originalTargetScale * cutCompleteScale, scaleUpDuration)
|
||||
.SetEase(Ease.OutQuad));
|
||||
|
||||
// 等待一段时间后开始淡出
|
||||
cutCompleteSequence.AppendInterval(fadeOutDelay);
|
||||
cutCompleteSequence.Append(targetSpriteRenderer.DOFade(0f, fadeOutDuration));
|
||||
|
||||
// 齿轮也同时淡出
|
||||
SpriteRenderer gearRenderer = GetComponent<SpriteRenderer>();
|
||||
if (gearRenderer != null)
|
||||
{
|
||||
// 计算随机方向
|
||||
float randomAngle = Random.Range(-cutCompleteTiltAngle, cutCompleteTiltAngle);
|
||||
Vector2 randomOffset = Random.insideUnitCircle * cutCompleteOffset;
|
||||
|
||||
// 立即应用倾斜和位移
|
||||
targetSpriteRenderer.transform.rotation = Quaternion.Euler(0, 0, randomAngle);
|
||||
targetSpriteRenderer.transform.position = originalTargetPosition + (Vector3)randomOffset;
|
||||
|
||||
// 创建动画序列
|
||||
cutCompleteSequence = DOTween.Sequence();
|
||||
|
||||
// 等待一段时间后开始放大
|
||||
cutCompleteSequence.AppendInterval(cutCompleteDelay);
|
||||
cutCompleteSequence.Append(targetSpriteRenderer.transform.DOScale(originalTargetScale * cutCompleteScale, scaleUpDuration)
|
||||
.SetEase(Ease.OutQuad));
|
||||
|
||||
// 等待一段时间后开始淡出
|
||||
cutCompleteSequence.AppendInterval(fadeOutDelay);
|
||||
cutCompleteSequence.Append(targetSpriteRenderer.DOFade(0f, fadeOutDuration));
|
||||
|
||||
// 齿轮也同时淡出
|
||||
SpriteRenderer gearRenderer = GetComponent<SpriteRenderer>();
|
||||
if (gearRenderer != null)
|
||||
cutCompleteSequence.Join(gearRenderer.DOFade(0f, fadeOutDuration));
|
||||
}
|
||||
cutCompleteSequence.OnComplete(() =>
|
||||
{
|
||||
cutCompleteSequence.Join(gearRenderer.DOFade(0f, fadeOutDuration));
|
||||
}
|
||||
|
||||
// 动画完成后销毁物体
|
||||
cutCompleteSequence.OnComplete(() => {
|
||||
Destroy(gameObject);
|
||||
if (targetSpriteRenderer != null)
|
||||
Destroy(this.gameObject);
|
||||
var cuttingManager = FixSystemCenter.SystemDic.Get<CuttingManager>();
|
||||
if (cuttingManager != null)
|
||||
{
|
||||
Destroy(targetSpriteRenderer.gameObject);
|
||||
cuttingManager.UpdateModule();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
|
||||
Reference in New Issue
Block a user