给线加入风力和空气阻力相关逻辑
This commit is contained in:
@@ -41538,8 +41538,8 @@ MonoBehaviour:
|
||||
Dependencies: []
|
||||
Tags:
|
||||
- Name: main/plyaer.bundle
|
||||
Hash: 33dc3a2319b9cf939df327449db4bddf
|
||||
Size: 378598574
|
||||
Hash: 3f8f7efec7b92de0aa2fee96a290c14b
|
||||
Size: 378598645
|
||||
Assets:
|
||||
- Path: Assets/ResRaw/Prefabs/Line/fishing line float set.prefab
|
||||
Address: Plyaer/fishing line float set
|
||||
|
||||
@@ -26,7 +26,7 @@ RenderSettings:
|
||||
m_AmbientIntensity: 0.8050667
|
||||
m_AmbientMode: 0
|
||||
m_SubtractiveShadowColor: {r: 0.8679245, g: 0.8679245, b: 0.8679245, a: 1}
|
||||
m_SkyboxMaterial: {fileID: 1769569826}
|
||||
m_SkyboxMaterial: {fileID: 16041075}
|
||||
m_HaloStrength: 0.5
|
||||
m_FlareStrength: 1
|
||||
m_FlareFadeSpeed: 3
|
||||
@@ -119,6 +119,54 @@ NavMeshSettings:
|
||||
debug:
|
||||
m_Flags: 0
|
||||
m_NavMeshData: {fileID: 0}
|
||||
--- !u!21 &16041075
|
||||
Material:
|
||||
serializedVersion: 8
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Enviro/Skybox
|
||||
m_Shader: {fileID: 4800000, guid: 34fee0a1b19b20b45aea7483b5f757da, type: 3}
|
||||
m_Parent: {fileID: 0}
|
||||
m_ModifiedSerializedProperties: 0
|
||||
m_ValidKeywords: []
|
||||
m_InvalidKeywords: []
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_LockedProperties:
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _GalaxyTex:
|
||||
m_Texture: {fileID: 8900000, guid: 5734983fc81450b4187c3cfa5985edef, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MoonGlowTex:
|
||||
m_Texture: {fileID: 2800000, guid: 6838e0810da4e49488b5d9a6ee76eb07, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MoonTex:
|
||||
m_Texture: {fileID: 2800000, guid: c6fd9f694390e0245b6dca5812065950, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _StarsTex:
|
||||
m_Texture: {fileID: 8900000, guid: b5a7175da0f133b4d951c19c9c2cebfc, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _SunTex:
|
||||
m_Texture: {fileID: 2800000, guid: c95bed5306e94f24ba5802d841607ac7, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Ints: []
|
||||
m_Floats: []
|
||||
m_Colors: []
|
||||
m_BuildTextureStacks: []
|
||||
m_AllowLocking: 1
|
||||
--- !u!1 &116710580
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -308,7 +356,7 @@ Transform:
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 135187477}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: -0, y: -0.7071068, z: -0, w: 0.7071068}
|
||||
m_LocalRotation: {x: -0, y: 0.38268346, z: -0, w: 0.92387956}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
@@ -325,8 +373,8 @@ WindZone:
|
||||
m_Enabled: 1
|
||||
m_Mode: 0
|
||||
m_Radius: 20
|
||||
m_WindMain: 0.25
|
||||
m_WindTurbulence: 0.25
|
||||
m_WindMain: 1
|
||||
m_WindTurbulence: 0
|
||||
m_WindPulseMagnitude: 0.5
|
||||
m_WindPulseFrequency: 0.01
|
||||
--- !u!1 &155834305
|
||||
@@ -541,7 +589,8 @@ Transform:
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Children:
|
||||
- {fileID: 2034802496}
|
||||
m_Father: {fileID: 965921865900907107}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &718680768
|
||||
@@ -1381,54 +1430,6 @@ Transform:
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!21 &1769569826
|
||||
Material:
|
||||
serializedVersion: 8
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Enviro/Skybox
|
||||
m_Shader: {fileID: 4800000, guid: 34fee0a1b19b20b45aea7483b5f757da, type: 3}
|
||||
m_Parent: {fileID: 0}
|
||||
m_ModifiedSerializedProperties: 0
|
||||
m_ValidKeywords: []
|
||||
m_InvalidKeywords: []
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_LockedProperties:
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _GalaxyTex:
|
||||
m_Texture: {fileID: 8900000, guid: 5734983fc81450b4187c3cfa5985edef, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MoonGlowTex:
|
||||
m_Texture: {fileID: 2800000, guid: 6838e0810da4e49488b5d9a6ee76eb07, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MoonTex:
|
||||
m_Texture: {fileID: 2800000, guid: c6fd9f694390e0245b6dca5812065950, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _StarsTex:
|
||||
m_Texture: {fileID: 8900000, guid: b5a7175da0f133b4d951c19c9c2cebfc, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _SunTex:
|
||||
m_Texture: {fileID: 2800000, guid: c95bed5306e94f24ba5802d841607ac7, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Ints: []
|
||||
m_Floats: []
|
||||
m_Colors: []
|
||||
m_BuildTextureStacks: []
|
||||
m_AllowLocking: 1
|
||||
--- !u!1 &1804549341
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -1487,6 +1488,59 @@ MonoBehaviour:
|
||||
_MaximumSpeed: 100
|
||||
_WarnOnSpeedClamp: 0
|
||||
_DebugSubsteps: 0
|
||||
--- !u!1 &2034802495
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 2034802496}
|
||||
- component: {fileID: 2034802497}
|
||||
m_Layer: 4
|
||||
m_Name: WaterCollider
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &2034802496
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2034802495}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 250, y: 0, z: 250}
|
||||
m_LocalScale: {x: 500, y: 1, z: 500}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 718680767}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!65 &2034802497
|
||||
BoxCollider:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2034802495}
|
||||
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_Size: {x: 1, y: 0.5, z: 1}
|
||||
m_Center: {x: 0, y: -0.27, z: 0}
|
||||
--- !u!1 &2079119365
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
|
||||
@@ -11,7 +11,7 @@ GameObject:
|
||||
- component: {fileID: 4439867113915692}
|
||||
- component: {fileID: 114581403422500557}
|
||||
- component: {fileID: 991521994724602848}
|
||||
m_Layer: 0
|
||||
m_Layer: 19
|
||||
m_Name: Fishing Line
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
@@ -61,7 +61,7 @@ MonoBehaviour:
|
||||
headMinLen: 0.01
|
||||
collisionMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 0
|
||||
m_Bits: 24
|
||||
constrainToGround: 1
|
||||
groundMask:
|
||||
serializedVersion: 2
|
||||
@@ -74,7 +74,7 @@ MonoBehaviour:
|
||||
waterRadius: 0.01
|
||||
renderSubdivisions: 6
|
||||
smooth: 1
|
||||
lineWidth: 0.01
|
||||
lineWidth: 0.005
|
||||
--- !u!120 &991521994724602848
|
||||
LineRenderer:
|
||||
serializedVersion: 2
|
||||
@@ -101,7 +101,7 @@ LineRenderer:
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
- {fileID: 0}
|
||||
- {fileID: 2100000, guid: 95a26dca51ebe9c4da5949631fa36027, type: 2}
|
||||
m_StaticBatchInfo:
|
||||
firstSubMesh: 0
|
||||
subMeshCount: 0
|
||||
@@ -690,7 +690,7 @@ MonoBehaviour:
|
||||
waterRadius: 0.01
|
||||
renderSubdivisions: 6
|
||||
smooth: 1
|
||||
lineWidth: 0.01
|
||||
lineWidth: 0.005
|
||||
--- !u!120 &484878994603287356
|
||||
LineRenderer:
|
||||
serializedVersion: 2
|
||||
@@ -717,7 +717,7 @@ LineRenderer:
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
- {fileID: 0}
|
||||
- {fileID: 2100000, guid: 95a26dca51ebe9c4da5949631fa36027, type: 2}
|
||||
m_StaticBatchInfo:
|
||||
firstSubMesh: 0
|
||||
subMeshCount: 0
|
||||
|
||||
@@ -86,7 +86,7 @@ public class SceneSettings : MonoBehaviour
|
||||
private void UpdateTimeOfDay()
|
||||
{
|
||||
var p = GameTimer.GetGameDayProgress();
|
||||
p = 0;
|
||||
// p = 0;
|
||||
// Debug.Log(p);
|
||||
EnviroManager.instance.Time.SetTimeOfDay(p * 24f);
|
||||
// if(AzureCoreSystem)
|
||||
|
||||
@@ -51,12 +51,19 @@ namespace NBF
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void LateUpdate()
|
||||
{
|
||||
UpdateMove();
|
||||
Fsm?.Update();
|
||||
|
||||
Data.EyeAngle = GameUtils.GetVerticalAngle(transform, FppLook);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace NBF
|
||||
|
||||
// Debug.Log($"addNum={addNum}");
|
||||
Player.ModelAsset.PlayerAnimator.FishingUp += addNum;
|
||||
Debug.LogError($"ishingFinal={Player.ModelAsset.PlayerAnimator.FishingUp}");
|
||||
// Debug.LogError($"ishingFinal={Player.ModelAsset.PlayerAnimator.FishingUp}");
|
||||
if (Player.ModelAsset.PlayerAnimator.FishingUp >= 1)
|
||||
{
|
||||
Player.ModelAsset.PlayerAnimator.FishingUp = 1;
|
||||
|
||||
@@ -41,11 +41,10 @@ public class Rope : MonoBehaviour
|
||||
[Header("Head Segment Clamp")] [Tooltip("第一段(起点->第1节点)允许的最小长度,避免收线时第一段被压到0导致数值炸")] [SerializeField, Min(0.0001f)]
|
||||
private float headMinLen = 0.01f;
|
||||
|
||||
|
||||
[Header("Collision Filter")]
|
||||
[SerializeField, Tooltip("只对这些Layer进行物理检测(Raycast/SphereCast等)。不在这里的层完全不检测。")]
|
||||
|
||||
[Header("Collision Filter")] [SerializeField, Tooltip("只对这些Layer进行物理检测(Raycast/SphereCast等)。不在这里的层完全不检测。")]
|
||||
private LayerMask collisionMask = ~0;
|
||||
|
||||
|
||||
[Header("Simple Ground/Water Constraint (Cheap)")] [SerializeField]
|
||||
private bool constrainToGround = true;
|
||||
|
||||
@@ -61,6 +60,32 @@ public class Rope : MonoBehaviour
|
||||
[Header("Render (High Resolution)")] [SerializeField, Min(1), Tooltip("每段物理线段插值加密的数量(越大越顺,越耗)")]
|
||||
private int renderSubdivisions = 6;
|
||||
|
||||
|
||||
[Header("Air / Wind (For Fishing Line Feel)")]
|
||||
[SerializeField, Range(0f, 5f), Tooltip("空气线性阻力(越大越不飘,空中更自然)")]
|
||||
private float airDrag = 0.9f;
|
||||
|
||||
[SerializeField, Range(0f, 2f), Tooltip("横向额外阻力(减少左右飘得太夸张)")]
|
||||
private float airDragXZ = 0.6f;
|
||||
|
||||
[SerializeField, Tooltip("风方向(世界空间)")]
|
||||
private Vector3 windDir = new Vector3(1f, 0f, 0f);
|
||||
|
||||
[SerializeField, Range(0f, 10f), Tooltip("基础风强度(m/s 级别的感觉)")]
|
||||
private float windStrength = 0.3f;
|
||||
|
||||
[SerializeField, Range(0f, 2f), Tooltip("阵风幅度(0=无阵风)")]
|
||||
private float windGust = 0.25f;
|
||||
|
||||
[SerializeField, Range(0.1f, 5f), Tooltip("阵风频率")]
|
||||
private float windFreq = 1.2f;
|
||||
|
||||
[Header("Bending (Smooth Curve)")]
|
||||
[SerializeField, Range(0f, 1f), Tooltip("抗折/弯曲刚度(0=完全不抗折,0.1~0.3 比较像鱼线)")]
|
||||
private float bendStiffness = 0.18f;
|
||||
|
||||
|
||||
|
||||
[SerializeField, Tooltip("是否使用 Catmull-Rom 平滑(推荐开启)")]
|
||||
private bool smooth = true;
|
||||
|
||||
@@ -98,7 +123,7 @@ public class Rope : MonoBehaviour
|
||||
AllocateAndInitNodes();
|
||||
RebuildRenderBufferIfNeeded();
|
||||
}
|
||||
|
||||
|
||||
private FRod _rod;
|
||||
|
||||
public void Init(FRod rod)
|
||||
@@ -121,7 +146,7 @@ public class Rope : MonoBehaviour
|
||||
maxPhysicsNodes = Mathf.Max(maxPhysicsNodes, minPhysicsNodes);
|
||||
|
||||
headMinLen = Mathf.Max(headMinLen, 0.0001f);
|
||||
|
||||
|
||||
// 如果你希望只用一个mask控制,避免 groundMask 忘了配
|
||||
if (groundMask == ~0)
|
||||
groundMask = collisionMask;
|
||||
@@ -137,15 +162,6 @@ public class Rope : MonoBehaviour
|
||||
|
||||
private void AllocateAndInitNodes()
|
||||
{
|
||||
// 若锚点存在:最小长度就是两锚点直线距离 + minSlack(防抖)
|
||||
// if (startAnchor && endAnchor)
|
||||
// {
|
||||
// float minFeasible = Vector3.Distance(startAnchor.position, endAnchor.position) + minSlack;
|
||||
// minFeasible -= 0.2f;
|
||||
// currentLength = Mathf.Max(currentLength, minFeasible);
|
||||
// targetLength = Mathf.Max(targetLength, minFeasible);
|
||||
// }
|
||||
|
||||
physicsNodes = Mathf.Clamp(ComputeDesiredNodes(currentLength), 2, maxPhysicsNodes);
|
||||
pCurr = new Vector3[physicsNodes];
|
||||
pPrev = new Vector3[physicsNodes];
|
||||
@@ -180,7 +196,7 @@ public class Rope : MonoBehaviour
|
||||
{
|
||||
targetLength = Mathf.Max(0f, lengthMeters);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public float GetCurrentLength() => currentLength;
|
||||
public float GetTargetLength() => targetLength;
|
||||
@@ -195,8 +211,8 @@ public class Rope : MonoBehaviour
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
private void FixedUpdate2()
|
||||
|
||||
private void FixedUpdate()
|
||||
{
|
||||
if (!startAnchor || !endAnchor)
|
||||
return;
|
||||
@@ -212,6 +228,7 @@ public class Rope : MonoBehaviour
|
||||
for (int it = 0; it < iterations; it++)
|
||||
{
|
||||
SolveDistanceConstraints_HeadOnly();
|
||||
SolveBendConstraint();
|
||||
LockAnchorsHard();
|
||||
}
|
||||
|
||||
@@ -221,10 +238,19 @@ public class Rope : MonoBehaviour
|
||||
LockAnchorsHard();
|
||||
}
|
||||
|
||||
|
||||
private void LateUpdate()
|
||||
{
|
||||
if (!startAnchor || !endAnchor || pCurr == null || physicsNodes < 2) return;
|
||||
|
||||
int last = physicsNodes - 1;
|
||||
Vector3 s = startAnchor.transform.position;
|
||||
Vector3 e = endAnchor.transform.position;
|
||||
|
||||
pCurr[0] = s; pPrev[0] = s; // ✅ 关键:同步 pPrev
|
||||
pCurr[last] = e; pPrev[last] = e; // ✅ 关键:同步 pPrev
|
||||
|
||||
DrawHighResLine();
|
||||
FixedUpdate2();
|
||||
}
|
||||
|
||||
private void UpdateLengthSmooth()
|
||||
@@ -348,18 +374,69 @@ public class Rope : MonoBehaviour
|
||||
private void Simulate()
|
||||
{
|
||||
float dt = Time.fixedDeltaTime;
|
||||
float invDt = 1f / Mathf.Max(dt, 1e-6f);
|
||||
|
||||
// 风方向归一化(避免填了0向量导致NaN)
|
||||
Vector3 wDir = windDir;
|
||||
if (wDir.sqrMagnitude < 1e-6f) wDir = Vector3.right;
|
||||
wDir.Normalize();
|
||||
|
||||
for (int i = 0; i < physicsNodes; i++)
|
||||
{
|
||||
Vector3 v = (pCurr[i] - pPrev[i]) * velocityDampen;
|
||||
pPrev[i] = pCurr[i];
|
||||
// Verlet 速度(由当前位置和上一帧位置推出来)
|
||||
Vector3 vel = (pCurr[i] - pPrev[i]) * invDt;
|
||||
|
||||
pCurr[i] += v;
|
||||
pCurr[i] += gravity * dt;
|
||||
// 先做“惯性推进”
|
||||
Vector3 next = pCurr[i] + (pCurr[i] - pPrev[i]) * velocityDampen;
|
||||
|
||||
// 加速度 = 重力 + 空气阻力 + 风(相对速度)
|
||||
Vector3 acc = gravity;
|
||||
|
||||
// --- 空气阻力(与速度成正比)---
|
||||
// drag = -vel * airDrag,并且横向更强一点
|
||||
Vector3 drag = -vel * airDrag;
|
||||
drag.x *= (1f + airDragXZ);
|
||||
drag.z *= (1f + airDragXZ);
|
||||
acc += drag;
|
||||
|
||||
// --- 风(让线在空中不那么“只会垂直掉”)---
|
||||
if (i != 0 && i != physicsNodes - 1 && windStrength > 0f)
|
||||
{
|
||||
float t = Time.time;
|
||||
float gust = 1f + Mathf.Sin(t * windFreq + i * 0.35f) * windGust;
|
||||
|
||||
// windVel:风希望空气把线速度拉向这个“风速”
|
||||
Vector3 windVel = wDir * (windStrength * gust);
|
||||
|
||||
// 相对风:让加速度朝 (windVel - vel) 方向
|
||||
// 系数越大,越“被风带着走”
|
||||
acc += (windVel - vel) * 0.5f;
|
||||
}
|
||||
|
||||
// Verlet:位置 += acc * dt^2
|
||||
pPrev[i] = pCurr[i];
|
||||
pCurr[i] = next + acc * (dt * dt);
|
||||
}
|
||||
|
||||
// 物理步末尾硬锁端点
|
||||
LockAnchorsHard();
|
||||
}
|
||||
|
||||
// private void Simulate()
|
||||
// {
|
||||
// float dt = Time.fixedDeltaTime;
|
||||
//
|
||||
// for (int i = 0; i < physicsNodes; i++)
|
||||
// {
|
||||
// Vector3 v = (pCurr[i] - pPrev[i]) * velocityDampen;
|
||||
// pPrev[i] = pCurr[i];
|
||||
//
|
||||
// pCurr[i] += v;
|
||||
// pCurr[i] += gravity * dt;
|
||||
// }
|
||||
//
|
||||
// LockAnchorsHard();
|
||||
// }
|
||||
|
||||
private void LockAnchorsHard()
|
||||
{
|
||||
@@ -367,7 +444,7 @@ public class Rope : MonoBehaviour
|
||||
float dt = Time.fixedDeltaTime;
|
||||
Vector3 s = startAnchor.position;
|
||||
Vector3 e = endAnchor.position;
|
||||
|
||||
|
||||
pCurr[0] = s;
|
||||
pPrev[0] = s - startAnchor.linearVelocity * dt;
|
||||
|
||||
@@ -399,6 +476,35 @@ public class Rope : MonoBehaviour
|
||||
pCurr[i + 1] -= corr * 0.5f;
|
||||
}
|
||||
}
|
||||
|
||||
private void SolveBendConstraint()
|
||||
{
|
||||
if (bendStiffness <= 0f) return;
|
||||
if (physicsNodes < 3) return;
|
||||
|
||||
// bendStiffness 在迭代里用太大很容易爆,先做一个安全钳制
|
||||
float kBase = Mathf.Clamp01(bendStiffness);
|
||||
|
||||
for (int i = 1; i < physicsNodes - 1; i++)
|
||||
{
|
||||
// 端点不要动(你本来就没动,这里保持)
|
||||
if (i == 0 || i == physicsNodes - 1) continue;
|
||||
|
||||
Vector3 mid = (pCurr[i - 1] + pCurr[i + 1]) * 0.5f;
|
||||
|
||||
float k = kBase;
|
||||
if (i <= 2) k *= 1.25f; // 靠近竿尖稍微更“直”一点
|
||||
|
||||
Vector3 old = pCurr[i];
|
||||
Vector3 newPos = Vector3.Lerp(old, mid, k);
|
||||
|
||||
Vector3 delta = newPos - old;
|
||||
|
||||
// ✅ 关键:同样把 pPrev 挪过去,避免“凭空制造速度”
|
||||
pCurr[i] = newPos;
|
||||
pPrev[i] += delta;
|
||||
}
|
||||
}
|
||||
|
||||
private void ConstrainToGroundAndWater()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user