using UnityEngine; using System.Collections.Generic; public class Buoyancy : MonoBehaviour { private Ocean ocean; private float mag = 1f; private float ypos = 0.0f; private List blobs; private float ax = 2.0f; private float ay = 2.0f; private float dampCoeff = .2f; public bool sink = false; public float sinkForce = 3; private List sinkForces; void Start() { rigidbody.centerOfMass = new Vector3(0.0f, -0.5f, 0.0f); Vector3 bounds = GetComponent().size; float length = bounds.z; float width = bounds.x; blobs = new List(); int i = 0; float xstep = 1.0f / (ax - 1f); float ystep = 1.0f / (ay - 1f); sinkForces = new List(); float totalSink = 0; for (int x = 0; x < ax; x++) { for (int y = 0; y < ay; y++) { blobs.Add(new Vector3((-0.5f + x * xstep) * width, 0.0f, (-0.5f + y * ystep) * length) + Vector3.up * ypos); float force = Random.Range(0f, 1f); force = force * force; totalSink += force; sinkForces.Add(force); i++; } } // normalize the sink forces for (int j = 0; j < sinkForces.Count; j++) { sinkForces[j] = sinkForces[j] / totalSink * sinkForce; } } void OnEnable() { if (ocean == null) ocean = GameObject.FindGameObjectWithTag("Ocean").GetComponent(); } void FixedUpdate() { int index = 0; Debug.Log(this.rigidbody.velocity); foreach (Vector3 blob in blobs) { Vector3 wpos = transform.TransformPoint(blob); float damp = rigidbody.GetPointVelocity(wpos).y; float buyancy = mag * (wpos.y); if (ocean.enabled && !sink) buyancy = mag * (wpos.y - ocean.GetWaterHeightAtLocation(wpos.x, wpos.z)); if (sink) { buyancy = Mathf.Max(buyancy, -3) + sinkForces[index++]; } rigidbody.AddRelativeForce(-Vector3.up * (buyancy + dampCoeff * damp), ForceMode.Impulse); //rigidbody.AddForceAtPosition(-Vector3.up * (buyancy + dampCoeff * damp), wpos); } } // Call this void when you want your boat or any object to sink more naturally public void Sink(bool isActive) { sink = isActive; } }