Skip to content

Instantly share code, notes, and snippets.

@d12
Last active August 7, 2020 17:59
Show Gist options
  • Save d12/376a48fcdf50c8fdc2876f1ddd4ef785 to your computer and use it in GitHub Desktop.
Save d12/376a48fcdf50c8fdc2876f1ddd4ef785 to your computer and use it in GitHub Desktop.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class FloatingObject : MonoBehaviour
{
Rigidbody rb;
// Linearly scales the force of buoyancy
// This has to be tuned based on the number of buoyancy points you define,
// the mass of your object, and the force of gravity (if you change it).
public float buoyancyForce = 1000f;
// A value between 0 and 1, higher dampenForce causes rotational energy
// to dampen faster. 0.01 seems good in my experience. Not needed if your water
// applies a force to your floating objects.
public float dampenForce = 0.01f;
// The height of your water.
// TODO: Be able to find the height of the water below the point
// This is easy with static water but very difficult with wavy water and no mesh collider on the water.
public float waterHeight = -1.8f;
void Awake() {
rb = GetComponent<Rigidbody>();
}
void FixedUpdate() {
Vector3[] objectCorners = ObjectCornersWorldSpace();
ApplyBuoyancyForces(objectCorners);
}
void ApplyBuoyancyForces(Vector3[] corners) {
foreach (Vector3 corner in corners)
{
// Squaring this number for a non-linear relationship between depth and buoyancy.
float depthInWaterForceFactor = Mathf.Pow(DepthInWater(corner.y), 2);
Vector3 force = Vector3.up * (depthInWaterForceFactor * buoyancyForce * Time.deltaTime);
rb.AddForceAtPosition(force, corner);
}
}
float DepthInWater(float objHeight){
return Mathf.Abs(waterHeight - objHeight);
}
void ApplyVelocityDapening() {
Vector3 velocity = rb.velocity;
velocity = velocity * (1 - dampenForce);
rb.velocity = velocity;
}
// This returns the four bottom corners of a cube in world space.
// To use this script with a non-cube, return at least 3 evenly spaced points
// on the bottom of your object.
Vector3[] ObjectCornersWorldSpace() {
Vector3[] vertices = new Vector3[4];
vertices[0] = transform.TransformPoint(new Vector3(.5f, -.5f, -.5f));
vertices[1] = transform.TransformPoint(new Vector3(.5f, -.5f, .5f));
vertices[2] = transform.TransformPoint(new Vector3(-.5f, -.5f, -.5f));
vertices[3] = transform.TransformPoint(new Vector3(-.5f, -.5f, .5f));
return vertices;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment