I am writing a endless runner using a water-based system, and found a buoyancy script named “Floater” that works very well. However, now I’d like to add rotation and forward movement, but I can’t find a way to add to the script without disrupting the force applied.
using UnityEngine;
using System.Collections;
public class Floater : MonoBehaviour {
public float waterLevel, floatHeight;
public Vector3 buoyancyCentreOffset;
public float bounceDamp;
private float yaw = 0;
void FixedUpdate () {
yaw = Input.GetAxis("Horizontal") * (Time.deltaTime * 30f);
Vector3 addRot = Vector3.zero;
addRot.y = yaw;
transform.Rotate(addRot);
Vector3 actionPoint = transform.position + transform.TransformDirection(buoyancyCentreOffset);
float forceFactor = 1f - ((actionPoint.y - waterLevel) / floatHeight);
if (forceFactor > 0f) {
Vector3 uplift = -Physics.gravity * (forceFactor - rigidbody.velocity.y * bounceDamp);
rigidbody.AddForceAtPosition(uplift, actionPoint);
Debug.Log (uplift);
}
}
}
You can include an AddForce in order to make it move in the desired direction - in this case, the object’s forward direction (you could instead use a world direction, like Vector3.forward).
...
public float bounceDamp;
public float force = 10.0f; // this is the move force
private float yaw = 0;
void FixedUpdate () {
yaw = Input.GetAxis("Horizontal") * (Time.deltaTime * 30f);
Vector3 addRot = Vector3.zero;
addRot.y = yaw;
transform.Rotate(addRot);
Vector3 actionPoint = transform.position + transform.TransformDirection(buoyancyCentreOffset);
float forceFactor = 1f - ((actionPoint.y - waterLevel) / floatHeight);
if (forceFactor > 0f) {
Vector3 uplift = -Physics.gravity * (forceFactor - rigidbody.velocity.y * bounceDamp);
rigidbody.AddForceAtPosition(uplift, actionPoint);
Debug.Log (uplift);
}
// add the movement force
float fwd = Input.GetAxis("Vertical") * Time.deltaTime * force;
rigidbody.AddForceAtPosition(fwd * transform.forward, actionPoint);
}
You could as well implement the rotation via AddTorque: the result would be more realistic (although many times we don’t want it too realistic) - example:
void FixedUpdate () {
yaw = -Input.GetAxis("Horizontal") * (Time.deltaTime * 5f);
rigidbody.AddTorque(new Vector3(0, yaw, 0)
Vector3 actionPoint = transform.position + transform.TransformDirection(buoyancyCentreOffset);
...
NOTE: Increase the Drag and AngularDrag to make the movement and rotation cease gradually when the force/torque are removed.