修改bobber浮力脚本

This commit is contained in:
Bob.Song
2026-03-03 15:50:04 +08:00
parent 23d06a1efc
commit bc7e3d3c44
23 changed files with 702 additions and 1740 deletions

View File

@@ -8,20 +8,14 @@ public class Buoyancy : MonoBehaviour
{
// public WaterSurface targetSurface;
public WaterRenderer _water;
[Tooltip("物体浮力的近似半径")] public float sphereRadiusApproximation = 0.25f;
public bool includeDeformation = true;
[Tooltip("指定由其他变形(波浪、涌浪等)引起的运动乘数。")] public float waveForceMultiplier = 1f;
[Tooltip("Approxative radius of object for buoyancy.")]
public float sphereRadiusApproximation = 0.25f;
[Tooltip("指定由水面水流引起的移动的乘数。")] public float currentSpeedMultiplier = 1f;
[Tooltip("Specifies the multiplier for the movement induced by other deformation (waves, swell... etc).")]
public float waveForceMultiplier = 1f;
[Tooltip("Specifies the multiplier for the movement induced by the current of the water surface.")]
public float currentSpeedMultiplier = 1f;
[Tooltip("Specifies the multiplier for the drag forces induced by the viscosity of the mediums.")]
public float dragMultiplier = 1f;
[Tooltip("指定由介质黏性所引起的阻力的乘数。")] public float dragMultiplier = 1f;
public float defaultRigidbodyDrag = 0.1f;
@@ -29,15 +23,13 @@ public class Buoyancy : MonoBehaviour
public float overwaterRigidbodyAngularDrag = 0.05f;
[Tooltip("Specifies the value for surface tension. A high value will stop the object bouncing faster on water.")]
[Tooltip("指定表面张力的数值。数值过高时,物体在水面上弹跳的速度会减慢。")]
public float surfaceTensionDamping = 10f;
[Tooltip("When enabled, the net force is applied with a random offset to create an angular velocity.")]
[Tooltip("启用后,净力会以随机偏移量施加出来,从而产生角速度。")]
public bool applyForceWithRandomOffset;
[Tooltip(
"When enabled, a bunch of gizmos will show showing in blue, the position of the sampling for normals, in magenta the computed normal, in green the direction of the deformation force, in red the direction of the current force, and in a yellow sphere, the approximation volume the buoyancy calculations.")]
public bool drawDebug;
[Tooltip("启用调试绘制")] public bool drawDebug;
private Vector3 currentDirection;
@@ -65,8 +57,7 @@ public class Buoyancy : MonoBehaviour
rigidbodyComponent.linearDamping = defaultRigidbodyDrag;
if (_water == null)
{
Debug.LogWarning(
"The variable '_water' needs a valid Water Surface to be assigned for the script to work properly.");
Debug.LogWarning("没有找到水组件");
}
}
@@ -90,59 +81,59 @@ public class Buoyancy : MonoBehaviour
rigidbodyComponent.useGravity = false;
// Cache frequently used values
// 缓存常用值
Vector3 pos = transform.position;
Vector3 velocity = rigidbodyComponent.linearVelocity;
float radius = sphereRadiusApproximation;
float diameter = 2f * radius;
// 1) Sample water surface at current position
// 1) 当前位置的水面示例图
FetchWaterSurfaceData(pos, out waterPosition, out normal, out currentDirection);
// Horizontal “wave push” direction derived from surface normal
// 水平“波浪推动”方向源自表面法线
deformationDirection = Vector3.ProjectOnPlane(normal, Vector3.up);
// 2) Submersion depth of the approximated sphere (0..2R)
// 2) 近似球体的浸没深度0 至 2R
float bottomY = pos.y - radius;
h = Mathf.Clamp(waterPosition.y - bottomY, 0f, diameter);
hNormalized = (diameter > 0f) ? (h / diameter) : 0f;
// 3) Submerged volume (spherical cap) V(h) = πh²/3 * (3R - h)
// 3) 浸没体积(球冠形) V(h) = πh²/3 * (3R - h)
float submergedVolume = MathF.PI * h * h / 3f * (3f * radius - h);
// 4) Angular damping transitions from air to water
// 4)角向阻尼从空气状态转变为水状态
rigidbodyComponent.angularDamping = Mathf.Lerp(
overwaterRigidbodyAngularDrag,
underwaterRigidbodyAngularDrag,
hNormalized
);
// 5) Forces (kept identical to your original math/units)
// 5) 力(保持与您原始的数学计算/单位一致)
Vector3 gravityAcceleration = Physics.gravity;
// NOTE: this is kept as-is (original mixes accel & force then uses Acceleration mode)
// 注意:保持原样(先将加速度和力相加,然后使用加速度模式)
Vector3 weightVector = rigidbodyComponent.mass * gravityAcceleration;
Vector3 gravityTerm = Vector3.Lerp(gravityAcceleration, weightVector, hNormalized);
// Physical constants (as in original)
// 物理常数(与原文相同)
const float rhoWater = 997f; // kg/m^3
const float rhoAir = 0.001293f; // kg/m^3
const float muAir = 0.0000181f; // Pa·s
const float muWater = 0.001f; // Pa·s
const float dragCoefficient = 0.47f;
// Buoyancy: -ρ * V * g
// 浮力: -ρ * V * g
Vector3 buoyancyTerm = (-rhoWater) * submergedVolume * gravityAcceleration;
// Linear viscous drag (Stokes-like): 6πRμ(-v) -> blend air/water by submersion
// 线性粘性阻力类似斯托克斯效应6πRμ(-v) -> 通过浸入使空气/水混合
Vector3 dragAir = MathF.PI * 6f * radius * muAir * (-velocity);
Vector3 dragWater = MathF.PI * 6f * radius * muWater * (-velocity);
Vector3 viscousDragTerm = Vector3.Lerp(dragAir, dragWater, hNormalized) * dragMultiplier;
// Net force (still applied as Acceleration)
// 合力(仍被视为加速度)
Vector3 netAcceleration = gravityTerm + buoyancyTerm + viscousDragTerm;
// Optional random offset to induce angular velocity
// 可选的随机偏移量,用于产生角速度
Vector3 randomOffset = Vector3.zero;
if (applyForceWithRandomOffset)
{
@@ -159,12 +150,12 @@ public class Buoyancy : MonoBehaviour
ForceMode.Acceleration
);
// 6) Extra forces only around the surface transition (0<hN<1)
// 6) 仅在表面过渡区域0 < hN < 1存在额外的力作用。
if (hNormalized > 0f && hNormalized < 1f)
{
Vector3 gravityDir = gravityAcceleration.normalized;
// Surface tension damping: cancels velocity along gravity direction
// 表面张力阻尼:抵消沿重力方向的速度
Vector3 verticalVelocity = Vector3.Dot(velocity, gravityDir) * gravityDir;
Vector3 surfaceTensionAccel = -verticalVelocity * surfaceTensionDamping;
@@ -173,7 +164,7 @@ public class Buoyancy : MonoBehaviour
rigidbodyComponent.AddForce(currentDirection * currentSpeedMultiplier, ForceMode.Acceleration);
}
// 7) Terminal velocity clamp (same formula, just named)
// 7) 终端速度夹具(公式相同,只是命名不同)
float area = MathF.PI * radius * radius;
float g = -gravityAcceleration.y; // positive value
@@ -221,6 +212,12 @@ public class Buoyancy : MonoBehaviour
Gizmos.DrawLine(base.transform.position, base.transform.position + currentDirection);
Gizmos.color = Color.yellow;
Gizmos.DrawSphere(base.transform.position, sphereRadiusApproximation);
// 绘制 Rigidbody 的重心点位
Vector3 centerOfMassWorld = transform.TransformPoint(rigidbodyComponent != null ? rigidbodyComponent.centerOfMass : Vector3.zero);
Gizmos.color = Color.cyan;
Gizmos.DrawSphere(centerOfMassWorld, 0.1f);
Gizmos.DrawLine(centerOfMassWorld, centerOfMassWorld + Vector3.up * 0.5f);
}
}
}