修改鱼线逻辑
This commit is contained in:
@@ -117,6 +117,10 @@ namespace NBF
|
||||
public void SetTargetLength(float value)
|
||||
{
|
||||
Log.Error($"SetObiRopeStretch={value}");
|
||||
if (value > 1)
|
||||
{
|
||||
// value -= 0.2f;
|
||||
}
|
||||
fishingRope.SetTargetLength(value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,10 +64,10 @@ public class Rope : MonoBehaviour
|
||||
|
||||
[SerializeField, Range(1, 8), Tooltip("每隔多少次FixedUpdate更新一次地面约束")]
|
||||
private int groundUpdateEvery = 2;
|
||||
|
||||
private int _groundFrameCounter;
|
||||
|
||||
[Header("Simple Water Float (Cheap)")]
|
||||
[SerializeField, Tooltip("绳子落到水面以下时,是否把节点约束回水面")]
|
||||
[Header("Simple Water Float (Cheap)")] [SerializeField, Tooltip("绳子落到水面以下时,是否把节点约束回水面")]
|
||||
private bool constrainToWaterSurface = true;
|
||||
|
||||
[SerializeField, Tooltip("静态水面高度;如果你后面接波浪水面,可改成采样函数")]
|
||||
@@ -236,7 +236,7 @@ public class Rope : MonoBehaviour
|
||||
|
||||
private int ComputeDesiredNodes(float lengthMeters)
|
||||
{
|
||||
int desired = Mathf.FloorToInt(Mathf.Max(0f, lengthMeters) / physicsSegmentLen) + 1;
|
||||
int desired = Mathf.RoundToInt(Mathf.Max(0f, lengthMeters) / physicsSegmentLen) + 1;
|
||||
desired = Mathf.Clamp(desired, minPhysicsNodes, maxPhysicsNodes);
|
||||
return desired;
|
||||
}
|
||||
@@ -284,7 +284,7 @@ public class Rope : MonoBehaviour
|
||||
|
||||
return totalLength;
|
||||
}
|
||||
|
||||
|
||||
public float GetPhysicsPolylineLength()
|
||||
{
|
||||
float total = 0f;
|
||||
@@ -322,10 +322,13 @@ public class Rope : MonoBehaviour
|
||||
|
||||
Simulate_VerletFast();
|
||||
|
||||
|
||||
LockAnchorsHard();
|
||||
|
||||
for (int it = 0; it < iterations; it++)
|
||||
SolveDistanceConstraints_HeadOnly_Fast();
|
||||
{
|
||||
SolveDistanceConstraints_FABRIK();
|
||||
}
|
||||
|
||||
LockAnchorsHard();
|
||||
|
||||
@@ -349,7 +352,9 @@ public class Rope : MonoBehaviour
|
||||
|
||||
// 水面抬升后补几次长度约束,让形状更顺一点
|
||||
for (int it = 0; it < waterPostConstraintIterations; it++)
|
||||
SolveDistanceConstraints_HeadOnly_Fast();
|
||||
{
|
||||
SolveDistanceConstraints_FABRIK();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -509,6 +514,58 @@ public class Rope : MonoBehaviour
|
||||
_pPrev[last] = e - endAnchor.linearVelocity * _dt;
|
||||
}
|
||||
|
||||
private void SolveDistanceConstraints_FABRIK()
|
||||
{
|
||||
int last = _physicsNodes - 1;
|
||||
if (last < 1) return;
|
||||
|
||||
// 起点固定
|
||||
_pCurr[0] = _startTr ? _startTr.position : startAnchor.position;
|
||||
|
||||
// Forward: from start to end
|
||||
for (int i = 1; i <= last; i++)
|
||||
{
|
||||
float rest = (i == 1) ? _headRestLen : physicsSegmentLen;
|
||||
|
||||
Vector3 prev = _pCurr[i - 1];
|
||||
Vector3 curr = _pCurr[i];
|
||||
Vector3 dir = curr - prev;
|
||||
float sq = dir.sqrMagnitude;
|
||||
|
||||
if (sq < 1e-12f)
|
||||
dir = Vector3.down;
|
||||
else
|
||||
dir /= Mathf.Sqrt(sq);
|
||||
|
||||
_pCurr[i] = prev + dir * rest;
|
||||
}
|
||||
|
||||
// 终点固定
|
||||
_pCurr[last] = _endTr ? _endTr.position : endAnchor.position;
|
||||
|
||||
// Backward: from end to start
|
||||
for (int i = last - 1; i >= 0; i--)
|
||||
{
|
||||
float rest = (i == 0) ? _headRestLen : physicsSegmentLen;
|
||||
|
||||
Vector3 next = _pCurr[i + 1];
|
||||
Vector3 curr = _pCurr[i];
|
||||
Vector3 dir = curr - next;
|
||||
float sq = dir.sqrMagnitude;
|
||||
|
||||
if (sq < 1e-12f)
|
||||
dir = Vector3.up;
|
||||
else
|
||||
dir /= Mathf.Sqrt(sq);
|
||||
|
||||
_pCurr[i] = next + dir * rest;
|
||||
}
|
||||
|
||||
// 再锁一次两端
|
||||
_pCurr[0] = _startTr ? _startTr.position : startAnchor.position;
|
||||
_pCurr[last] = _endTr ? _endTr.position : endAnchor.position;
|
||||
}
|
||||
|
||||
private void SolveDistanceConstraints_HeadOnly_Fast()
|
||||
{
|
||||
int last = _physicsNodes - 1;
|
||||
@@ -528,8 +585,23 @@ public class Rope : MonoBehaviour
|
||||
float diff = (dist - rest) / dist;
|
||||
Vector3 corr = delta * (diff * stiffness);
|
||||
|
||||
if (i != 0) _pCurr[i] = a + corr * 0.5f;
|
||||
if (i + 1 != last) _pCurr[i + 1] = b - corr * 0.5f;
|
||||
bool aLocked = (i == 0);
|
||||
bool bLocked = (i + 1 == last);
|
||||
|
||||
if (!aLocked && !bLocked)
|
||||
{
|
||||
_pCurr[i] = a + corr * 0.5f;
|
||||
_pCurr[i + 1] = b - corr * 0.5f;
|
||||
}
|
||||
else if (aLocked && !bLocked)
|
||||
{
|
||||
_pCurr[i + 1] = b - corr; // 首段:node1 吃满
|
||||
}
|
||||
else if (!aLocked && bLocked)
|
||||
{
|
||||
_pCurr[i] = a + corr; // 尾段:last-1 吃满
|
||||
}
|
||||
// 两边都锁的情况理论上不会出现
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user