I have searched the forum but couldn’t find this
I am attempting this:
I’d like to be able to throw boxes and other meshes inside a pool of water.
The water should have an “upwards force” based on a property of the object
that falls into the water (“driftness”).
But can’t seem to get the “springyness” that you can see when stuff is floating on water. Does anyone has a tip (perhaps did a similair thing before)?
You can actually treat the surface of the water as if it were a spring. Subtract the y-coordinate of the water plane from the y-coordinate of the buoyant object. The difference is equivalent to the extension of a spring - you can simply multiply this value by a small “buoyancy” factor stored in the object script (make this a public variable so you can tweak its value at runtime). Obviously, you should ignore the spring when its value is positive (ie, the object is out of the water) - you don’t want the water to attract the object down onto its surface.
The spring you get will be bouncy (ie, it will keep rebounding) but this is probably a desirable effect in this case. You wouldn’t want a car spring to keep oscillating after a bump, but water is naturally bumpy, of course. Add a bit of randomness for a more realistic effect and damp the spring slightly if the water is supposed to be calm.
Unless the objects are perfectly regular, they will most likely have a “centre of buoyancy” which is generally not the same as the centre of mass. Offset the centre of mass slightly from the geometric origin and apply the upward force through the origin using the Rigidbody’s AddForceAtPosition method (again, use a public variable to get a tweakable vector). The heavy end of the object should then sink lower than the floaty end.
Here’s a slightly improved version of the code above… doesn’t modify velocities directly and assuming the collider is oriented along z applies force at the more submerged end. Needs more work to be general, but it looks more natural.
var density = 997.0479; //density of the liquid in which the object floats... d=mass(kg)/volume(m3)... density of water is 997.0479 at 77 degrees F
var water : Transform;
function FixedUpdate () {
if (transform.position.y < water.position.y)
{
var volume = collider.bounds.size.x*collider.bounds.size.y*collider.bounds.size.z;
var frontPoint=(collider.bounds.center+Vector3(0,0,collider.bounds.extents.z));
var rearPoint=(collider.bounds.center-Vector3(0,0,collider.bounds.extents.z));
var submergedVolume = volume*Mathf.Min(1,-(collider.bounds.center.y-collider.bounds.extents.y)/collider.bounds.size.y);
var rootRB = transform.root.rigidbody;
var buoyantForce = Vector3(0,-density*submergedVolume*Physics.gravity.y,0);
if(frontPoint.y<rearPoint.y) rootRB.AddForceAtPosition(buoyantForce,collider.bounds.center+Vector3(0,0,collider.bounds.extents.z/2));
else if(frontPoint.y>rearPoint.y) rootRB.AddForceAtPosition(buoyantForce,collider.bounds.center-Vector3(0,0,collider.bounds.extents.z/2));
else rootRB.AddForceAtPosition(buoyantForce,collider.bounds.center);
}
}