diff --git a/Assets/New Terrain 13.asset b/Assets/New Terrain 13.asset new file mode 100644 index 000000000..aa5a057c1 Binary files /dev/null and b/Assets/New Terrain 13.asset differ diff --git a/Assets/New Terrain 13.asset.meta b/Assets/New Terrain 13.asset.meta new file mode 100644 index 000000000..71dedac44 --- /dev/null +++ b/Assets/New Terrain 13.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 953400dda9b03df4d967e2e7dd8ef9f8 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 15600000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Fishing/Rope/Rope.cs b/Assets/Scripts/Fishing/Rope/Rope.cs index 03a9cf3a8..e4e60a055 100644 --- a/Assets/Scripts/Fishing/Rope/Rope.cs +++ b/Assets/Scripts/Fishing/Rope/Rope.cs @@ -31,6 +31,12 @@ public class Rope : MonoBehaviour [SerializeField, Range(0, 16), Tooltip("主求解后追加的硬长度约束次数。只负责把 poly 拉回到 rest total,不改变可变长度逻辑")] private int hardTightenIterations = 2; + [SerializeField, Range(0, 32), Tooltip("当绳子接近拉直时,按误差自动追加的硬长度约束次数上限")] + private int adaptiveHardTightenMaxIterations = 8; + + [SerializeField, Min(0f), Tooltip("单段允许的最大超长误差;超过时继续追加硬长度约束")] + private float hardConstraintTolerance = 0.0005f; + [Header("Length Control (No Min/Max Clamp)")] [Tooltip("初始总长度(米)。如果为 0,则用 physicsSegmentLen*(minPhysicsNodes-1) 作为初始长度")] [SerializeField, Min(0f)] @@ -211,6 +217,8 @@ public class Rope : MonoBehaviour renderSubdivisionsMoving = Mathf.Max(renderSubdivisionsMoving, 1); iterations = Mathf.Clamp(iterations, 1, 80); hardTightenIterations = Mathf.Clamp(hardTightenIterations, 0, 16); + adaptiveHardTightenMaxIterations = Mathf.Clamp(adaptiveHardTightenMaxIterations, 0, 32); + hardConstraintTolerance = Mathf.Max(0f, hardConstraintTolerance); groundCastDistance = Mathf.Max(groundCastDistance, 0.01f); groundCastHeight = Mathf.Max(groundCastHeight, 0f); lineWidth = Mathf.Max(lineWidth, 0.0001f); @@ -532,6 +540,7 @@ public class Rope : MonoBehaviour } SolveHardDistanceConstraints(hardTightenIterations); + SolveHardDistanceConstraintsAdaptive(); LockAnchorsHard(); if (constrainToGround) @@ -572,16 +581,7 @@ public class Rope : MonoBehaviour EnsureRenderCaches(); int last = _physicsNodes - 1; - - Vector3 s = _startTr.position; - Vector3 e = _endTr.position; - - _pCurr[0] = s; - _pCurr[last] = e; - // _pPrev[0] = s; - // _pPrev[last] = e; - - DrawHighResLine_Fast(); + DrawHighResLine_Fast(_startTr.position, _endTr.position, last); } private void UpdateLengthSmooth() @@ -734,6 +734,21 @@ public class Rope : MonoBehaviour } } + private void SolveHardDistanceConstraintsAdaptive() + { + if (adaptiveHardTightenMaxIterations <= 0 || hardConstraintTolerance <= 0f) + return; + + for (int it = 0; it < adaptiveHardTightenMaxIterations; it++) + { + if (GetMaxPositiveSegmentDelta() <= hardConstraintTolerance) + break; + + LockAnchorsHard(); + SolveDistanceConstraints_HeadOnly_Hard(); + } + } + private void SolveDistanceConstraints_HeadOnly_Hard() { SolveDistanceConstraints_HeadOnly_Bidirectional(1f); @@ -787,6 +802,21 @@ public class Rope : MonoBehaviour } } + private float GetMaxPositiveSegmentDelta() + { + float maxDelta = 0f; + for (int i = 1; i < _physicsNodes; i++) + { + float rest = (i == 1) ? _headRestLen : physicsSegmentLen; + float segLen = Vector3.Distance(_pCurr[i - 1], _pCurr[i]); + float delta = segLen - rest; + if (delta > maxDelta) + maxDelta = delta; + } + + return maxDelta; + } + private void ConstrainToGround() { if (groundMask == 0) return; @@ -938,7 +968,7 @@ public class Rope : MonoBehaviour } } - private void DrawHighResLine_Fast() + private void DrawHighResLine_Fast(Vector3 renderStart, Vector3 renderEnd, int last) { if (_pCurr == null || _physicsNodes < 2) return; @@ -949,7 +979,9 @@ public class Rope : MonoBehaviour if (!smooth) { _lineRenderer.positionCount = _physicsNodes; - _lineRenderer.SetPositions(_pCurr); + for (int i = 0; i <= last; i++) + _rPoints[i] = GetRenderPoint(i, last, renderStart, renderEnd); + _lineRenderer.SetPositions(_rPoints); return; } @@ -964,7 +996,6 @@ public class Rope : MonoBehaviour } int idx = 0; - int last = _physicsNodes - 1; for (int seg = 0; seg < last; seg++) { @@ -975,10 +1006,10 @@ public class Rope : MonoBehaviour int i3 = seg + 2; if (i3 > last) i3 = last; - Vector3 p0 = _pCurr[i0]; - Vector3 p1 = _pCurr[i1]; - Vector3 p2 = _pCurr[i2]; - Vector3 p3 = _pCurr[i3]; + Vector3 p0 = GetRenderPoint(i0, last, renderStart, renderEnd); + Vector3 p1 = GetRenderPoint(i1, last, renderStart, renderEnd); + Vector3 p2 = GetRenderPoint(i2, last, renderStart, renderEnd); + Vector3 p3 = GetRenderPoint(i3, last, renderStart, renderEnd); for (int s = 0; s < subdiv; s++) { @@ -1001,12 +1032,21 @@ public class Rope : MonoBehaviour } } - _rPoints[idx++] = _pCurr[last]; + _rPoints[idx++] = renderEnd; _lineRenderer.positionCount = idx; _lineRenderer.SetPositions(_rPoints); } + private Vector3 GetRenderPoint(int index, int last, Vector3 renderStart, Vector3 renderEnd) + { + if (index <= 0) + return renderStart; + if (index >= last) + return renderEnd; + return _pCurr[index]; + } + private static float ClampMonotonic(float value, float p0, float p1, float p2, float p3) { bool rising = p0 <= p1 && p1 <= p2 && p2 <= p3; diff --git a/UserSettings/EditorUserSettings.asset b/UserSettings/EditorUserSettings.asset index c70116ffe..20fec54ca 100644 --- a/UserSettings/EditorUserSettings.asset +++ b/UserSettings/EditorUserSettings.asset @@ -15,32 +15,32 @@ EditorUserSettings: value: 2550581500 flags: 0 RecentlyUsedSceneGuid-0: - value: 55540305570d0f0e0c5e5e2115710d44174e4e2b7b7e77662f2d1c61b5b06069 - flags: 0 - RecentlyUsedSceneGuid-1: - value: 5452500303515f0a5f5b5a7445775e46401519787c717f677d784860e3b1676c - flags: 0 - RecentlyUsedSceneGuid-2: value: 050402550007590a0f565f2714200c44144e492f2f70753175711f66e0b8303c flags: 0 - RecentlyUsedSceneGuid-3: + RecentlyUsedSceneGuid-1: value: 06070c5f5c075c5e5e085476427a0a44474e1c2f7f7a73362f2d4d36b5b1633d flags: 0 - RecentlyUsedSceneGuid-4: + RecentlyUsedSceneGuid-2: value: 0005505f515750595e5f5f23412507441216497f2d7f24367e711c64b6b86c61 flags: 0 - RecentlyUsedSceneGuid-5: - value: 54070c5452075002590c0871127b5a4443161c2f797176312c2f1e6bb1b4353d - flags: 0 - RecentlyUsedSceneGuid-6: + RecentlyUsedSceneGuid-3: value: 5309035757065a0a54575f7216265c4444151d28792e72627d2f1935bbb8673a flags: 0 - RecentlyUsedSceneGuid-7: + RecentlyUsedSceneGuid-4: value: 00050c5150005f5f54560f2640270d4410161c28282b72357e7c4835e4b63760 flags: 0 - RecentlyUsedSceneGuid-8: + RecentlyUsedSceneGuid-5: value: 06090c5f54015f5a0f085b7b11765d444e4e1e287429773178704561b3b23561 flags: 0 + RecentlyUsedSceneGuid-6: + value: 0257035f51050d090f0f5d734521094414164e797e7a20667d7a4536e0e36461 + flags: 0 + RecentlyUsedSceneGuid-7: + value: 54070c5452075002590c0871127b5a4443161c2f797176312c2f1e6bb1b4353d + flags: 0 + RecentlyUsedSceneGuid-8: + value: 07060c5454040c0a545b547240700a441216417e7f2e7268752c4966b4b0663d + flags: 0 RecentlyUsedSceneGuid-9: value: 5505015f5c515a085f5b092149760f441716407a787d7564287b1b36e7e1366e flags: 0