Make an Object float on water in Unity

Unity has never been good with water physics. The same is true for buoyancy. Making an object float on water in Unity is not as simple as attaching a rigidbody. But if you are creative enough you can write your own buoyancy script and make the object float. In this tutorial, we will see how you can make an object look like its floating using animation and use a script to add buoyancy force. The first one is an easy way out though.

Unity water is just a surface with water shader and some wave script. If you place a rigidbody on place it will just stay there. If the plane doesn’t have a collider then the physics object will just pass through it. Now if you have a object without rigidbody then the best way to make it float will be using an animation.

I am using the low poly water asset from the Unity asset store for this demo.

Make an object float Using Animation

Object floating with Animation

Our scene has an ocean and an island. Lets add a cube to the scene and place it just above the water. The low poly water asset has option to adjust ripples, lets go with smooth ripples. Now if you play the game the waves are moving but the cube is still.

Lets add some animation to move the cube up and down. Any object floating on water will always be partially submerged in water. Keep the initial position of the cube in a way that it just touches the water. Adjust position for different keyframes to make the cube partially submerged. That’s it the animation is ready.

Animator Window Unity

Make an object float Using physics

The concept of using physics is very similar to buoyancy force. An upward force should act on the object when its sinking and by default the gravity tries to bring in down. So you need to find an appropriate value for your force to make sure that the object does not bounce out of water. This is the script I used on my object to float. The water is at origin so the position can be taken as zero.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class buoyancy : MonoBehaviour
{
    [SerializeField]
    float buoyancy_force;
    Rigidbody rig;
    // Start is called before the first frame update
    void Start()
    {
        rig=GetComponent<Rigidbody>();
    }

    // Update is called once per frame
    void Update()
    {
       float y_pos= transform.position.y;
       if(y_pos<0)
       {
         rig.AddForce(transform.up*buoyancy_force);  
       } 
    }
}

The result is almost similar. Physics makes it look more realistic.

Object floating with Physics in Unity

Conclusion

Both methods produce great results and our object seems to be floating. But if you have hundreds of objects in your scene that needs to float on object then, using physics will cause a performance issue. But in case of physics, you can just attach the script to the game object and its starts floating. Animation is not reusable like the script so you need to animate all the objects that requires to float.

To overcome the performance issue you can activate the script only when the object comes into camera view. This way the number of update function running at any time will be less.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.