公式
F浮 = ρ液gV排
(浮力单位为N,液体密度单位为kg / m3,重力加速度单位为m / s2,体积单位为m3)
实现方法
创建一个平面,为了让它透明,将其翻转180度,使其正面朝下
再将其默认的Mesh Collider移除,替换成Box Collider,并将其设置为触发器
将其包围盒的下方高度设置得足够大,然后将平面的大小调整到与海平面一致
最后给平面添加脚本,配置相关参数:
ρ 液体密度 (kg / m3)
G 重力加速度 (m / s2)
Sea Level 海平面高度
如果物体要受到浮力作用,则需要给它添加碰撞体和刚体。
在播放模式下,不断地调整物体的质量,寻找一个合适的数值,使其能够平静地浮于水面。
比如将游戏角色Riko,身高158cm,将其体重设置为38.5kg时,恰好能在水中悬浮。
可以适当调整角阻力 Angular Drag,避免物体在水中一直旋转,也可以直接冻结刚体的旋转。
此外,该脚本直接限制了物体各轴的速度,如无外力,在一定时间内将停止运动。
效果
代码
using UnityEngine;
public class Buoyancy : MonoBehaviour
{
public float ρ = 1000;
public float g = 9.81f;
public float SeaLevel = 3;
private void OnTriggerStay(Collider collision)
{
if (collision != null)
{
collision.attachedRigidbody.velocity =
new Vector3(Mathf.Lerp(collision.attachedRigidbody.velocity.x, 0, 0.005f),
Mathf.Lerp(collision.attachedRigidbody.velocity.y, 0, 0.01f),
Mathf.Lerp(collision.attachedRigidbody.velocity.z, 0, 0.005f));
float Depth = SeaLevel - collision.transform.position.y + collision.bounds.extents.y;
float LengthBesideWater = Mathf.Clamp(Depth,0,collision.bounds.size.y);
float V = collision.bounds.size.x * LengthBesideWater * collision.bounds.size.z;
collision.attachedRigidbody.AddForce(new Vector3(0, ρ * g * V, 0),ForceMode.Force);
//print(collision.name+" 深度:"+ Depth + " 水下部分高度:" + LengthBesideWater + " 水下部分体积:" + V + " 浮力:" + ρ * g * V);
}
}
}
附
Unity 船的控制
|