修改线的渲染长度不一致问题
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user