Hi,I’ve a problem,how can i floating a object(ship) on the water? :shock:
Welcome to the forum Tahamtan!
You can create a simple buoyancy effect by adding a force to your object depending on how high it is above the water level. When it is exactly at the water level, the force should be exactly equal to gravity. Above a certain height, the object is completely out of the water and gets no lift from floating.
The key to getting a good floating effect is that the place where the buoyancy force is applied is not generally the same as the object’s centre of mass. For example, a car’s centre of mass will be located near the engine, but its “centre of buoyancy” will be in the passenger compartment where all the air is.
I’ve attached an example project with a script that applies forces to a simple object. It works OK for a floating object with a fairly regular shape, but you might want to add more points of buoyancy if you are modelling, say, a large boat.
Post again if you have any questions about this.
206376–7610–$buoyancyunitypackage_191.zip (5.42 KB)
206376–12520–$jsfloater_166.js (467 Bytes)
Thank you very much, you`re the best
Hey Andeeee,
I’ve been looking for a similar ‘lightweight’ bouyancy script but am having trouble importing your unity package. It seems to unzip as a folder instead of a unitypackage.
Any chance of reuploading (I’m using Unity Indie 2.6 if that is the problem?) and perhaps a tiny rundown of whats happening in the script and/or how to apply it?
Cheers
Steveo
If the .unitypackage file is appearing as a folder, it is because the browser or unzip program is not stopping after the first decompression (the package itself is a compressed file). I think you can just re-zip the folder once and rename it with a .unitypackage suffix. Either that or turn off automatic decompression in the browser when you download it.
Anyway… the basic concept behind buoyancy is that the object is being pulled down by gravity, but there is an uplifting force supplied by the water. The uplift increases with the object’s depth. So, for a buoyant object, there is a kind of balance point where the gravity pulling down is equal to the uplift. Floating an object, then, is a matter of defining a level for the surface of the water and applying an upward force proportional to the distance of the object below the water level.
By default, gravity and other forces are applied at the rigidbody’s centre of mass. However, you get a much more interesting buoyancy effect if you apply the uplift in a slightly different position in the object, a “centre of buoyancy”, so to speak. (If you think about a car floating/sinking, the mass is concentrated around the engine, but the passenger compartment is where all the air is.) You can use rigidbody.AddForceAtPosition to apply the uplift somewhere other than the centre of mass.
A slight complication is that any balancing of forces like this will tend to make the object oscillate endlessly back and forth around the balance point. In a situation like this, you can damp the oscillation by reducing the force applied in proportion to the speed the object is moving. An analogy for this is that it is easy to push down firmly on a bicycle’s pedals when it is moving slowly, but they move away from under your feet when it is going fast.
So… the script firstly establishes where the object’s centre of buoyancy is. It then calculates how far below the water level that point currently is. The uplift is exactly equal to gravity when this point is exactly at the water level, but increases in proportion to the object’s depth. An amount proportional to the object’s upward speed is then subtracted from the uplift force (this is the damping) and the resulting force is applied at the centre of buoyancy.
Like many physics scripts, it’s a few lines of code but a lot more lines of text to explain
Whoa, that was much more than i expected! Yep got it working, thanks heaps for your help mate.
Steveo
Hi! I loved the Buoyancy script, it worked great! I was working on adapting it for my game, but I realized that it was in C#, a language in which I am clueless. I wondered about doing a raycast to find the distance to the ground so the script could constantly update the water level (i’m working on a hovercar style game), but I only know javascript. Would you know how to do a raycast in C#, or happen to have a javascript version of this lying around?
thanks for the brief physics lesson and the script really helped me out.
I’ve nothing much to add really, except regarding andeeee’s response here. I’m a scripting newbie and a slow learner by anyone’s standards, but thanks to having both a decent description about how the code works and being able to dissect the script myself I’ve learnt more going through this in a matter of minutes than I did in hours of going through hundreds of other responses to queries. This kinda stuff is above and beyond the call of duty, so for what it’s worth I’m really impressed. Cheers!
I’m not sure exactly what you mean here. Do you need to detect the distance from the hovercar to the water, or the level of the water plane above the ground or… ?
Im telling you guys, andeee’s a genius…
Hello everyone!
First thank you Andeeee for buoyancy script!
It works on my boat but the only problem is that the water came inside the boat (a classic wooden boat) at the intersection between them. Is there any trick that i can do to avoid that happen?
P.S. srry for my bad english.
If I understand you right, the problem is the graphical effect of the water plane appearing inside the boat. You can use the depth mask shader from the Unify wiki to fix this.
wow it works… Thank you again!!
he really is a genius 0.0
I think everyone would agree with that statement. Andddddeeeeee needs to consolidate all his gems and put them on the wiki.
Thanks to Andeeee for the script.
I do have one problem though, changing the water height seems to mess up the buoyancy of the objects. I dug through the script but couldnt find the bug - any ideas?
That would take years out of his lifetime!
I do have one problem though, changing the water height seems to mess up the buoyancy of the objects.
I’ve just tried playing with the water height, and it seems OK on my (admittedly simple) test project. When you say the buoyancy is messed up, what exactly is going wrong?
If you change the water plane Y, the block will end up floating just under water - very different from the Y = 0 (see pics). Also if you monitor the submerged volume, the number will go out of the 0 to 1 range when the water plane is moved (I suspect the tet slicing code has a bug) I worked around it by using multiple buoyancy spheres (less accurate, but probably faster).