绳子绑定
This commit is contained in:
@@ -714,6 +714,7 @@ GameObject:
|
|||||||
- component: {fileID: 963194228}
|
- component: {fileID: 963194228}
|
||||||
- component: {fileID: 963194227}
|
- component: {fileID: 963194227}
|
||||||
- component: {fileID: 963194226}
|
- component: {fileID: 963194226}
|
||||||
|
- component: {fileID: 963194229}
|
||||||
m_Layer: 0
|
m_Layer: 0
|
||||||
m_Name: Main Camera
|
m_Name: Main Camera
|
||||||
m_TagString: MainCamera
|
m_TagString: MainCamera
|
||||||
@@ -795,6 +796,50 @@ Transform:
|
|||||||
m_Children: []
|
m_Children: []
|
||||||
m_Father: {fileID: 0}
|
m_Father: {fileID: 0}
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
--- !u!114 &963194229
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 963194225}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: a79441f348de89743a2939f4d699eac1, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_RenderShadows: 1
|
||||||
|
m_RequiresDepthTextureOption: 2
|
||||||
|
m_RequiresOpaqueTextureOption: 2
|
||||||
|
m_CameraType: 0
|
||||||
|
m_Cameras: []
|
||||||
|
m_RendererIndex: -1
|
||||||
|
m_VolumeLayerMask:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Bits: 1
|
||||||
|
m_VolumeTrigger: {fileID: 0}
|
||||||
|
m_VolumeFrameworkUpdateModeOption: 2
|
||||||
|
m_RenderPostProcessing: 0
|
||||||
|
m_Antialiasing: 0
|
||||||
|
m_AntialiasingQuality: 2
|
||||||
|
m_StopNaN: 0
|
||||||
|
m_Dithering: 0
|
||||||
|
m_ClearDepth: 1
|
||||||
|
m_AllowXRRendering: 1
|
||||||
|
m_AllowHDROutput: 1
|
||||||
|
m_UseScreenCoordOverride: 0
|
||||||
|
m_ScreenSizeOverride: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
m_ScreenCoordScaleBias: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
m_RequiresDepthTexture: 0
|
||||||
|
m_RequiresColorTexture: 0
|
||||||
|
m_Version: 2
|
||||||
|
m_TaaSettings:
|
||||||
|
m_Quality: 3
|
||||||
|
m_FrameInfluence: 0.1
|
||||||
|
m_JitterScale: 1
|
||||||
|
m_MipBias: 0
|
||||||
|
m_VarianceClampScale: 0.9
|
||||||
|
m_ContrastAdaptiveSharpening: 0
|
||||||
--- !u!1 &1418847128
|
--- !u!1 &1418847128
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@@ -932,11 +977,12 @@ MonoBehaviour:
|
|||||||
m_Script: {fileID: 11500000, guid: daf71302d510df147b3f07dee056e8fd, type: 3}
|
m_Script: {fileID: 11500000, guid: daf71302d510df147b3f07dee056e8fd, type: 3}
|
||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
mouseOffset: 10
|
startAttachment: {fileID: 1670765576}
|
||||||
nodeDistance: 0.1
|
endAttachment: {fileID: 1778778649}
|
||||||
|
nodeDistance: 0.05
|
||||||
nodeColliderRadius: 0.3
|
nodeColliderRadius: 0.3
|
||||||
gravityStrength: 1.962
|
gravityStrength: 1.962
|
||||||
totalLength: 6
|
totalLength: 30
|
||||||
velocityDampen: 0.95
|
velocityDampen: 0.95
|
||||||
stiffness: 0.99
|
stiffness: 0.99
|
||||||
iterateCollisionsEvery: 1
|
iterateCollisionsEvery: 1
|
||||||
@@ -1177,6 +1223,129 @@ Transform:
|
|||||||
m_Children: []
|
m_Children: []
|
||||||
m_Father: {fileID: 0}
|
m_Father: {fileID: 0}
|
||||||
m_LocalEulerAnglesHint: {x: -90, y: 0, z: 0}
|
m_LocalEulerAnglesHint: {x: -90, y: 0, z: 0}
|
||||||
|
--- !u!1 &1670765571
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 1670765576}
|
||||||
|
- component: {fileID: 1670765575}
|
||||||
|
- component: {fileID: 1670765574}
|
||||||
|
- component: {fileID: 1670765573}
|
||||||
|
- component: {fileID: 1670765572}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: Start
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!114 &1670765572
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1670765571}
|
||||||
|
m_Enabled: 0
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: f32dd1b0ec37b4443afde8d3426a4257, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
radius: 1
|
||||||
|
angularSpeed: 100
|
||||||
|
--- !u!135 &1670765573
|
||||||
|
SphereCollider:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1670765571}
|
||||||
|
m_Material: {fileID: 0}
|
||||||
|
m_IncludeLayers:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Bits: 0
|
||||||
|
m_ExcludeLayers:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Bits: 0
|
||||||
|
m_LayerOverridePriority: 0
|
||||||
|
m_IsTrigger: 0
|
||||||
|
m_ProvidesContacts: 0
|
||||||
|
m_Enabled: 1
|
||||||
|
serializedVersion: 3
|
||||||
|
m_Radius: 0.5
|
||||||
|
m_Center: {x: 0, y: 0, z: 0}
|
||||||
|
--- !u!23 &1670765574
|
||||||
|
MeshRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1670765571}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_CastShadows: 1
|
||||||
|
m_ReceiveShadows: 1
|
||||||
|
m_DynamicOccludee: 1
|
||||||
|
m_StaticShadowCaster: 0
|
||||||
|
m_MotionVectors: 1
|
||||||
|
m_LightProbeUsage: 1
|
||||||
|
m_ReflectionProbeUsage: 1
|
||||||
|
m_RayTracingMode: 2
|
||||||
|
m_RayTraceProcedural: 0
|
||||||
|
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||||
|
m_RayTracingAccelStructBuildFlags: 1
|
||||||
|
m_SmallMeshCulling: 1
|
||||||
|
m_RenderingLayerMask: 1
|
||||||
|
m_RendererPriority: 0
|
||||||
|
m_Materials:
|
||||||
|
- {fileID: 2100000, guid: 5365763285455e743bcff11042adedb5, type: 2}
|
||||||
|
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_AdditionalVertexStreams: {fileID: 0}
|
||||||
|
--- !u!33 &1670765575
|
||||||
|
MeshFilter:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1670765571}
|
||||||
|
m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0}
|
||||||
|
--- !u!4 &1670765576
|
||||||
|
Transform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1670765571}
|
||||||
|
serializedVersion: 2
|
||||||
|
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||||
|
m_LocalPosition: {x: -1.38, y: 0, z: 0}
|
||||||
|
m_LocalScale: {x: 0.5, y: 0.5, z: 0.5}
|
||||||
|
m_ConstrainProportionsScale: 0
|
||||||
|
m_Children: []
|
||||||
|
m_Father: {fileID: 0}
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
--- !u!1 &1770539745
|
--- !u!1 &1770539745
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@@ -1287,6 +1456,129 @@ Transform:
|
|||||||
m_Children: []
|
m_Children: []
|
||||||
m_Father: {fileID: 0}
|
m_Father: {fileID: 0}
|
||||||
m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0}
|
m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0}
|
||||||
|
--- !u!1 &1778778644
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 1778778649}
|
||||||
|
- component: {fileID: 1778778648}
|
||||||
|
- component: {fileID: 1778778647}
|
||||||
|
- component: {fileID: 1778778646}
|
||||||
|
- component: {fileID: 1778778645}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: End
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!114 &1778778645
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1778778644}
|
||||||
|
m_Enabled: 0
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: f32dd1b0ec37b4443afde8d3426a4257, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
radius: 1
|
||||||
|
angularSpeed: 100
|
||||||
|
--- !u!135 &1778778646
|
||||||
|
SphereCollider:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1778778644}
|
||||||
|
m_Material: {fileID: 0}
|
||||||
|
m_IncludeLayers:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Bits: 0
|
||||||
|
m_ExcludeLayers:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Bits: 0
|
||||||
|
m_LayerOverridePriority: 0
|
||||||
|
m_IsTrigger: 0
|
||||||
|
m_ProvidesContacts: 0
|
||||||
|
m_Enabled: 1
|
||||||
|
serializedVersion: 3
|
||||||
|
m_Radius: 0.5
|
||||||
|
m_Center: {x: 0, y: 0, z: 0}
|
||||||
|
--- !u!23 &1778778647
|
||||||
|
MeshRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1778778644}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_CastShadows: 1
|
||||||
|
m_ReceiveShadows: 1
|
||||||
|
m_DynamicOccludee: 1
|
||||||
|
m_StaticShadowCaster: 0
|
||||||
|
m_MotionVectors: 1
|
||||||
|
m_LightProbeUsage: 1
|
||||||
|
m_ReflectionProbeUsage: 1
|
||||||
|
m_RayTracingMode: 2
|
||||||
|
m_RayTraceProcedural: 0
|
||||||
|
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||||
|
m_RayTracingAccelStructBuildFlags: 1
|
||||||
|
m_SmallMeshCulling: 1
|
||||||
|
m_RenderingLayerMask: 1
|
||||||
|
m_RendererPriority: 0
|
||||||
|
m_Materials:
|
||||||
|
- {fileID: 2100000, guid: 5365763285455e743bcff11042adedb5, type: 2}
|
||||||
|
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_AdditionalVertexStreams: {fileID: 0}
|
||||||
|
--- !u!33 &1778778648
|
||||||
|
MeshFilter:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1778778644}
|
||||||
|
m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0}
|
||||||
|
--- !u!4 &1778778649
|
||||||
|
Transform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1778778644}
|
||||||
|
serializedVersion: 2
|
||||||
|
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||||
|
m_LocalPosition: {x: 2.14, y: 0, z: 0}
|
||||||
|
m_LocalScale: {x: 0.5, y: 0.5, z: 0.5}
|
||||||
|
m_ConstrainProportionsScale: 0
|
||||||
|
m_Children: []
|
||||||
|
m_Father: {fileID: 0}
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
--- !u!1 &1790524738
|
--- !u!1 &1790524738
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@@ -1700,6 +1992,8 @@ SceneRoots:
|
|||||||
- {fileID: 1418847131}
|
- {fileID: 1418847131}
|
||||||
- {fileID: 272993070}
|
- {fileID: 272993070}
|
||||||
- {fileID: 7476150}
|
- {fileID: 7476150}
|
||||||
|
- {fileID: 1670765576}
|
||||||
|
- {fileID: 1778778649}
|
||||||
- {fileID: 1930140672}
|
- {fileID: 1930140672}
|
||||||
- {fileID: 601989252}
|
- {fileID: 601989252}
|
||||||
- {fileID: 1790524742}
|
- {fileID: 1790524742}
|
||||||
|
|||||||
@@ -3,8 +3,10 @@ using UnityEngine;
|
|||||||
[RequireComponent(typeof(LineRenderer))]
|
[RequireComponent(typeof(LineRenderer))]
|
||||||
public class Rope : MonoBehaviour
|
public class Rope : MonoBehaviour
|
||||||
{
|
{
|
||||||
[Header("Demo Parameters")] [SerializeField, Min(0)]
|
[Header("Attachment Points")] [SerializeField]
|
||||||
float mouseOffset = 10f;
|
public Transform startAttachment; // 绳子起点绑定的Transform
|
||||||
|
|
||||||
|
[SerializeField] public Transform endAttachment; // 绳子终点绑定的Transform
|
||||||
|
|
||||||
[Header("Verlet Parameters")] [SerializeField]
|
[Header("Verlet Parameters")] [SerializeField]
|
||||||
float nodeDistance = 0.35f;
|
float nodeDistance = 0.35f;
|
||||||
@@ -22,12 +24,7 @@ public class Rope : MonoBehaviour
|
|||||||
float ropeWidth = 0.1f;
|
float ropeWidth = 0.1f;
|
||||||
|
|
||||||
// 私有变量
|
// 私有变量
|
||||||
Camera cam;
|
|
||||||
Vector3 gravity;
|
Vector3 gravity;
|
||||||
Vector3 startLock;
|
|
||||||
Vector3 endLock;
|
|
||||||
bool isStartLocked = false;
|
|
||||||
bool isEndLocked = false;
|
|
||||||
|
|
||||||
// 数组和缓存
|
// 数组和缓存
|
||||||
Vector3[] currentNodePositions;
|
Vector3[] currentNodePositions;
|
||||||
@@ -37,13 +34,12 @@ public class Rope : MonoBehaviour
|
|||||||
GameObject nodeTester;
|
GameObject nodeTester;
|
||||||
SphereCollider nodeCollider;
|
SphereCollider nodeCollider;
|
||||||
int totalNodes;
|
int totalNodes;
|
||||||
float lastTotalLength; // 用于检测长度变化
|
float lastTotalLength;
|
||||||
|
|
||||||
void Awake()
|
void Awake()
|
||||||
{
|
{
|
||||||
// 获取组件引用
|
// 获取组件引用
|
||||||
lineRenderer = GetComponent<LineRenderer>();
|
lineRenderer = GetComponent<LineRenderer>();
|
||||||
cam = Camera.main;
|
|
||||||
gravity = new Vector3(0, -gravityStrength, 0);
|
gravity = new Vector3(0, -gravityStrength, 0);
|
||||||
|
|
||||||
// 初始化节点测试器
|
// 初始化节点测试器
|
||||||
@@ -63,7 +59,6 @@ public class Rope : MonoBehaviour
|
|||||||
totalNodes = Mathf.FloorToInt(totalLength / nodeDistance) + 1;
|
totalNodes = Mathf.FloorToInt(totalLength / nodeDistance) + 1;
|
||||||
float remainingLength = totalLength % nodeDistance;
|
float remainingLength = totalLength % nodeDistance;
|
||||||
|
|
||||||
// 如果剩余长度大于0,增加一个节点
|
|
||||||
if (remainingLength > 0 && totalLength > nodeDistance)
|
if (remainingLength > 0 && totalLength > nodeDistance)
|
||||||
{
|
{
|
||||||
totalNodes++;
|
totalNodes++;
|
||||||
@@ -75,18 +70,13 @@ public class Rope : MonoBehaviour
|
|||||||
colliderHitBuffer = new Collider[colliderBufferSize];
|
colliderHitBuffer = new Collider[colliderBufferSize];
|
||||||
|
|
||||||
// 初始化节点位置
|
// 初始化节点位置
|
||||||
Vector3 startPos = transform.position;
|
Vector3 startPos = startAttachment != null ? startAttachment.position : transform.position;
|
||||||
for (int i = 0; i < totalNodes; i++)
|
for (int i = 0; i < totalNodes; i++)
|
||||||
{
|
{
|
||||||
// 如果是最后一个节点且有剩余长度,使用剩余长度
|
|
||||||
float distance = (i == totalNodes - 1 && remainingLength > 0) ? remainingLength : nodeDistance;
|
float distance = (i == totalNodes - 1 && remainingLength > 0) ? remainingLength : nodeDistance;
|
||||||
|
|
||||||
// 如果数组已有数据,保持现有位置,否则初始化新位置
|
currentNodePositions[i] = startPos;
|
||||||
if (currentNodePositions[i] == null)
|
previousNodePositions[i] = startPos;
|
||||||
{
|
|
||||||
currentNodePositions[i] = startPos;
|
|
||||||
previousNodePositions[i] = startPos;
|
|
||||||
}
|
|
||||||
startPos.y -= distance;
|
startPos.y -= distance;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,54 +95,28 @@ public class Rope : MonoBehaviour
|
|||||||
lastTotalLength = totalLength;
|
lastTotalLength = totalLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理鼠标输入
|
|
||||||
if (Input.GetMouseButtonDown(0))
|
|
||||||
{
|
|
||||||
if (!isStartLocked)
|
|
||||||
{
|
|
||||||
isStartLocked = true;
|
|
||||||
startLock = GetMouseWorldPosition();
|
|
||||||
}
|
|
||||||
else if (!isEndLocked)
|
|
||||||
{
|
|
||||||
isEndLocked = true;
|
|
||||||
endLock = GetMouseWorldPosition();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!isStartLocked)
|
|
||||||
{
|
|
||||||
startLock = GetMouseWorldPosition();
|
|
||||||
}
|
|
||||||
else if (isStartLocked && !isEndLocked)
|
|
||||||
{
|
|
||||||
endLock = GetMouseWorldPosition();
|
|
||||||
}
|
|
||||||
|
|
||||||
DrawRope();
|
DrawRope();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdjustRopeLength()
|
void AdjustRopeLength()
|
||||||
{
|
{
|
||||||
// 保存旧位置
|
|
||||||
Vector3[] oldPositions = (Vector3[])currentNodePositions.Clone();
|
Vector3[] oldPositions = (Vector3[])currentNodePositions.Clone();
|
||||||
Vector3[] oldPrevPositions = (Vector3[])previousNodePositions.Clone();
|
Vector3[] oldPrevPositions = (Vector3[])previousNodePositions.Clone();
|
||||||
|
|
||||||
// 重新初始化绳索
|
|
||||||
InitializeRope();
|
InitializeRope();
|
||||||
|
|
||||||
// 尽可能保留旧位置数据
|
|
||||||
int copyLength = Mathf.Min(oldPositions.Length, currentNodePositions.Length);
|
int copyLength = Mathf.Min(oldPositions.Length, currentNodePositions.Length);
|
||||||
System.Array.Copy(oldPositions, currentNodePositions, copyLength);
|
System.Array.Copy(oldPositions, currentNodePositions, copyLength);
|
||||||
System.Array.Copy(oldPrevPositions, previousNodePositions, copyLength);
|
System.Array.Copy(oldPrevPositions, previousNodePositions, copyLength);
|
||||||
|
|
||||||
// 如果长度增加,初始化新增节点的位置
|
|
||||||
if (currentNodePositions.Length > oldPositions.Length)
|
if (currentNodePositions.Length > oldPositions.Length)
|
||||||
{
|
{
|
||||||
Vector3 lastPos = oldPositions[oldPositions.Length - 1];
|
Vector3 lastPos = oldPositions[oldPositions.Length - 1];
|
||||||
for (int i = oldPositions.Length; i < currentNodePositions.Length; i++)
|
for (int i = oldPositions.Length; i < currentNodePositions.Length; i++)
|
||||||
{
|
{
|
||||||
float distance = (i == currentNodePositions.Length - 1 && (totalLength % nodeDistance) > 0) ?
|
float distance = (i == currentNodePositions.Length - 1 && (totalLength % nodeDistance) > 0)
|
||||||
(totalLength % nodeDistance) : nodeDistance;
|
? (totalLength % nodeDistance)
|
||||||
|
: nodeDistance;
|
||||||
|
|
||||||
lastPos.y -= distance;
|
lastPos.y -= distance;
|
||||||
currentNodePositions[i] = lastPos;
|
currentNodePositions[i] = lastPos;
|
||||||
@@ -169,7 +133,6 @@ public class Rope : MonoBehaviour
|
|||||||
{
|
{
|
||||||
ApplyConstraint();
|
ApplyConstraint();
|
||||||
|
|
||||||
// 减少碰撞检测频率
|
|
||||||
if (i % (iterateCollisionsEvery + 1) == 0)
|
if (i % (iterateCollisionsEvery + 1) == 0)
|
||||||
{
|
{
|
||||||
AdjustCollisions();
|
AdjustCollisions();
|
||||||
@@ -177,17 +140,11 @@ public class Rope : MonoBehaviour
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 GetMouseWorldPosition()
|
|
||||||
{
|
|
||||||
return cam.ScreenToWorldPoint(Input.mousePosition + new Vector3(0, 0, mouseOffset));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Simulate()
|
void Simulate()
|
||||||
{
|
{
|
||||||
float fixedDt = Time.fixedDeltaTime;
|
float fixedDt = Time.fixedDeltaTime;
|
||||||
for (int i = 0; i < totalNodes; i++)
|
for (int i = 0; i < totalNodes; i++)
|
||||||
{
|
{
|
||||||
// 计算并应用速度
|
|
||||||
Vector3 velocity = (currentNodePositions[i] - previousNodePositions[i]) * velocityDampen;
|
Vector3 velocity = (currentNodePositions[i] - previousNodePositions[i]) * velocityDampen;
|
||||||
previousNodePositions[i] = currentNodePositions[i];
|
previousNodePositions[i] = currentNodePositions[i];
|
||||||
currentNodePositions[i] += velocity + gravity * fixedDt;
|
currentNodePositions[i] += velocity + gravity * fixedDt;
|
||||||
@@ -196,14 +153,18 @@ public class Rope : MonoBehaviour
|
|||||||
|
|
||||||
void ApplyConstraint()
|
void ApplyConstraint()
|
||||||
{
|
{
|
||||||
// 锁定端点
|
// 绑定到起点Transform
|
||||||
currentNodePositions[0] = startLock;
|
if (startAttachment != null)
|
||||||
if (isStartLocked && isEndLocked)
|
|
||||||
{
|
{
|
||||||
currentNodePositions[totalNodes - 1] = endLock;
|
currentNodePositions[0] = startAttachment.position;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 绑定到终点Transform
|
||||||
|
if (endAttachment != null)
|
||||||
|
{
|
||||||
|
currentNodePositions[totalNodes - 1] = endAttachment.position;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 预计算所有常用值
|
|
||||||
float halfStiffness = 0.5f * stiffness;
|
float halfStiffness = 0.5f * stiffness;
|
||||||
int nodeCountMinusOne = totalNodes - 1;
|
int nodeCountMinusOne = totalNodes - 1;
|
||||||
|
|
||||||
@@ -213,14 +174,13 @@ public class Rope : MonoBehaviour
|
|||||||
Vector3 node2 = currentNodePositions[i + 1];
|
Vector3 node2 = currentNodePositions[i + 1];
|
||||||
Vector3 diff = node1 - node2;
|
Vector3 diff = node1 - node2;
|
||||||
|
|
||||||
// 计算期望的距离 - 如果是最后一个段且有剩余长度,使用剩余长度
|
float desiredDistance = (i == nodeCountMinusOne - 1 && (totalLength % nodeDistance) > 0)
|
||||||
float desiredDistance = (i == nodeCountMinusOne - 1 && (totalLength % nodeDistance) > 0) ?
|
? (totalLength % nodeDistance)
|
||||||
(totalLength % nodeDistance) : nodeDistance;
|
: nodeDistance;
|
||||||
|
|
||||||
float sqrDesiredDistance = desiredDistance * desiredDistance;
|
float sqrDesiredDistance = desiredDistance * desiredDistance;
|
||||||
float sqrDistance = diff.x * diff.x + diff.y * diff.y + diff.z * diff.z;
|
float sqrDistance = diff.x * diff.x + diff.y * diff.y + diff.z * diff.z;
|
||||||
|
|
||||||
// 只有当距离差异超过一定阈值时才调整
|
|
||||||
if (Mathf.Abs(sqrDistance - sqrDesiredDistance) > 0.001f)
|
if (Mathf.Abs(sqrDistance - sqrDesiredDistance) > 0.001f)
|
||||||
{
|
{
|
||||||
float distance = Mathf.Sqrt(sqrDistance);
|
float distance = Mathf.Sqrt(sqrDistance);
|
||||||
@@ -276,4 +236,11 @@ public class Rope : MonoBehaviour
|
|||||||
Destroy(nodeTester);
|
Destroy(nodeTester);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 公开方法用于动态设置绑定点
|
||||||
|
public void SetAttachments(Transform start, Transform end)
|
||||||
|
{
|
||||||
|
startAttachment = start;
|
||||||
|
endAttachment = end;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user