Search Unity

  1. We've closed the job boards. If you're looking for work, or looking to hire check out Unity Connect. You can see more information here.
    Dismiss Notice
  2. Unity 2017.3 has arrived! Read about it here.
    Dismiss Notice
  3. Unity’s Demo Team is excited to share their upcoming interactive demo, Book of the Dead. See more information here.
    Dismiss Notice
  4. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice

Buoyancy script

Discussion in 'Made With Unity' started by alexzzzz, Jan 6, 2011.

  1. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,304
    Just Archimedes' law:



    Requires a collider and rigidbody components.

    P.S.
    I've updated the script:
    1) The old one didn't take into account object rotation and consequently produced wrong results sometimes.
    2) The new one draws nice gizmos

    P.P.S.
    Version 2.1

    1. I decided to not calculate density from volume, because volume "calculation" itself is quite inaccurate. It's easer to specify the correct density manually.
    2. Now it works with concave shapes too. Thanks to Antitheory for the idea.

    P.P.P.S.
    License: WTFPL version 2.
     

    Attached Files:

    Last edited: May 27, 2016
  2. granada

    granada

    Joined:
    Oct 31, 2010
    Posts:
    135
    Looks great,i can see me floating away on a raft :D.

    Dave
     
  3. cupsster

    cupsster

    Joined:
    Apr 14, 2009
    Posts:
    363
    nice presentation.. will give it a try. Thank You for sharing.
     
  4. 7loop7

    7loop7

    Joined:
    Oct 29, 2009
    Posts:
    40
    looks very cool, will have to give it a try later.
    thanks you =)
     
  5. 3dDude

    3dDude

    Joined:
    Jul 4, 2010
    Posts:
    1,064
    man that water shader rocks!!!! maybe a package for that to??? :D thanks!
     
  6. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,428
    Nicely done. I noted the "links" to the ocean shader that were commented out. Does it work with the community ocean shader?
     
  7. dart

    dart

    Joined:
    Jan 9, 2010
    Posts:
    208
    Nice work. Thanks for sharing
     
  8. Antitheory

    Antitheory

    Joined:
    Nov 14, 2010
    Posts:
    549
    The Ocean script/shader by Nikko has a buoyancy script to that works similar to this, although that one is only two-dimensional (ie: it doesn't chop the object along the y-axis).

    I just made my own little version of the same script in order to make it work semi-realistically with irregular objects. The problem with the approach taken here is that it simply gets the bounds (a rectangular prism) of the collider and chops that up into cubes... this means that a cone, for example, would have just as much buoyancy at it's tip as at it's base (obviously not true).

    To solve this problem I use basically the same approach as this script, but each point is checked to see if it's truly "inside" the collider. I accomplished this by firing 6 rays originating outside the mesh toward the point. each ray corresponds to a direction along the x,y,z axes. If any of the rays don't hit the collider it mean's the point does not reside inside the mesh. There can be some false-positives, but only for very concave shapes.

    The script is designed to work with the Ocean script but it could be easily modified to work with any water plane. If there is interest I'll post the script here.
     
  9. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,428
    Thanks Antitheory. I'd love to see your enhanced script as well.
     
  10. DjOscar527

    DjOscar527

    Joined:
    Nov 15, 2009
    Posts:
    800
    Looks really awesome, thanks for sharing!
     
  11. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,304
    3dDude,
    It's a community ocean shader:

    http://www.unifycommunity.com/wiki/index.php?title=Ocean_Shader_Project
    http://forum.unity3d.com/threads/16540-Wanted-Ocean-shader

    Yes, it does.

    Actually, the ocean package comes with its own buoyancy script. I looked at it, got the idea, and wrote this one from scratch. Then, in order to avoid the defective javascript<>c# interoperability, I translated the whole ocean script to c# for my personal use.

    Here it is:
     

    Attached Files:

  12. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,304
    Nice idea!
     
  13. Antitheory

    Antitheory

    Joined:
    Nov 14, 2010
    Posts:
    549
    EDIT

    I removed my version of the script because it had some errors in it. I have fixed them now and will clean-up the code a bit so you guys can check it out. I tested it out with composite objects too. I made a pretty sweet catamaran... I will post it all soon in a new thread.
     
    Last edited: Jan 6, 2011
  14. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,304
    I have updated my buoyancy script, because the old one produces wrong results if an object is rotated. Check the first post.
     
  15. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,304
    Does anyone remember how floating boxes should look?

    [​IMG]

    Is this 45 degree angle ok?
     
  16. Antitheory

    Antitheory

    Joined:
    Nov 14, 2010
    Posts:
    549
    I get the same effect when using cubes... I don't know whether that is what it would actually look like or not. Considering that all the cubes are doing that then there is either a real-life physics reason or a programming-error physics reason. It's just a guess, but it may have something to do with fluid dynamics...

    In most cases though objects like a crate don't have their center of gravity right in the middle anyways... usually it's closer to the bottom because the stuff inside is heavier nearer the bottom (or you are packing your crates wrong!). If you imbalance your cubes they might end up floating more level...

    EDIT:

    Now that I think about it some more I may have the reason why. It's because the only way to calculate the buoyancy affect on an individual chunk of the object is to the proportion of it which is underwater... however when the chunk is rotated the proportion is not linearly related to the chunk's center point's position relative to the water-level.
     
    Last edited: Jan 6, 2011
  17. granada

    granada

    Joined:
    Oct 31, 2010
    Posts:
    135
    In real life i sapose you would get both :confused:.

    dave
     
  18. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,428
    A floating object is considered "at rest" when the center of buoyancy is directly above the center of gravity. I don't recall what an ideal cube's resting point is, but I'd guess it's pretty much what you're seeing which is similar to an ideal sphere which has no resting point (the center of gravity and center of buoyancy are in the same location).
     
    Last edited: Jan 6, 2011
  19. Antitheory

    Antitheory

    Joined:
    Nov 14, 2010
    Posts:
    549
    Very interesting... I just read up on ship-design, center of buoyancy, "metacenters" and what not. Pretty interesting stuff...
     
  20. granada

    granada

    Joined:
    Oct 31, 2010
    Posts:
    135
    Been thinking about this to,i think random is the word :confused: :)confused: but then again i usualy am :D)

    Dave
     
  21. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,304
    Anyway, if someone's crates are packed well, he should change the line

    rigidbody.centerOfMass = new Vector3(0, -bounds.extents.y * 0, 0) + transform.InverseTransformPoint(bounds.center);

    into something like this

    rigidbody.centerOfMass = new Vector3(0, -bounds.extents.y * 0.2f, 0) + transform.InverseTransformPoint(bounds.center);

    [​IMG]
     
  22. psychicparrot

    psychicparrot

    Joined:
    Dec 10, 2007
    Posts:
    870
    Thanks for sharing - this is an awesome script!
     
  23. souperdave

    souperdave

    Joined:
    Jan 7, 2011
    Posts:
    7
    Looks awesome Alex, will try it soon and hope I can make something useful for you one day :)

    Dave
     
  24. reissgrant

    reissgrant

    Joined:
    Aug 20, 2009
    Posts:
    727
    This looks great! Thanks for sharing! :D
     
  25. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,304
    Update: version 2.1 works with concave objects. Check the first post.
     
    Last edited: Jan 7, 2011
  26. Antitheory

    Antitheory

    Joined:
    Nov 14, 2010
    Posts:
    549
    Heh, glad to be of help.

    I've got another challenge for you. I upgraded my own script again... I would post it here but it's kinda messy.

    Now the shapes are analyzed using the 6 ray hit test at a very high resolution, and then sampled down to create a "fuzzy" voxelmap. Now the voxels (or chunks or sectors or whatever you want to call them) are Vector4s, the fourth property being the volume of the voxel itself (as a proportion of a full voxel).

    This way I can sample a 4m x 4m x 4m sphere with over 35000 chunks, (which calculates a nearly accurate volume of 33.7 cubic m) and downsample it 4 times to 27 chunks, the volume stays the same but now the physics engine only has to do 27 AddForces every fixedupdate instead of an unwieldy 35000. Not only do you get the correct volume, but you also get proper buoyancy on irregular objects (as we multiply the chunk buoyancy by it's fourth property (the volume of the voxel).

    The downside is that it takes about a second to calculate the 35000 chunks, however I made a little routine to save the downsampled data into a file which can be loaded at runtime.

    One more thing: I used Physics.raycast to get the collision info so I can get the volume data for composite colliders. First I build a list of all the colliders which are in the buoyant objects hierarchy and build a bounds around them all. I also get the layer of each of the colliders to add to a layermask, so we can ensure that the Physics.raycast does not catch other objects. (I also only cast as far as I need to, from the edge of the bounds to the point itself).
     
  27. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,428
    @alexzzzz - Your buoyancy script is absolutely brilliant! I've been experimenting with it and the updated ocean.cs you posted. It fixes a number of issues that existed before and the buoyancy seems very realistic. Thanks very much! :)

    One thing I noticed in all the buoyancy scripts I've seen is that it doesn't take into account the "center of gravity" (abbreviated COG and also called center of mass) of the floating object. For any object that isn't composed of a 100% homogeneous material, the COG will likely not be at the same location as the center of buoyancy. In something like a boat, the COG is intentionally placed as low as possible to keep the boat topside up (that's why they use lead keels in sailboats).

    With alexzzzz's script I tried using the Unity rigidbody.centerofmass function but it didn't seem to have any effect. That sort of surprised me because it normally has a very obvious effect in other rigidbodies. Any ideas why it didn't effect it?
     
    Last edited: Jan 15, 2011
  28. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,304
  29. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,428
    Thanks Alexzzzz, that's the answer! :)
     
  30. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,428
    @alexzzzz - I've been having some fun with your script and have a couple questions:

    How should I be setting the rigidbody's MASS and the script's DENSITY settings? It appears you're using kg/m**3 as a unit of measure for the water density. So then, what effect do the script's DENSITY and the rigidbody's MASS have?

    Also, I'm having a hard time understanding how to set SlicesPerAxis and VoxelsLimit, they aren't behaving as I might expect them to. If I pick, for example, 3 Slices per Axis shouldn't that result in 3 * 3 slices which would mean a VoxelLimit of 9? I guess I'm not understanding that part. I also found that if I set either of these two variables too big the Unity editor locks up (oops!).

    I'm also finding that for a simple object, like a 2 x 4 x 8 unit box, the slices / voxels tend to be placed towards one end of the box rather than evenly distributed. The result is that the box doesn't float evenly. How do I set things so it behaves properly?

    Thanks very much for sharing this with us. I'm having a lot of fun with it! :)
     
  31. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,304
    I have introduced a separate Density property, because it's hard to calculate the real density of an object, because it's hard and sometimes impossible to calculate it's volume (for example, most trees have no bottom). So, now we have two properties:

    1) buoyancy.density
    The main rule is simple:
    density < 1000 => will float
    density > 1000 => will not

    The most kinds of wood have the density in 500–700 range. So, if you have something made of wood, set its density according to that knowledge. If it looks not good for some reason, feel free to increase or reduce it.

    Buoyancy force depends on density.

    2) rigidbody.mass
    Set it to something real, because the script applies buoyancy forces to the object. If the mass is too low, the acceleration will be too high and the object might be shot up in the air, or will bounce above the water surface.

    Acceleration depends on buoyancy force and mass.

    Step 1: The object is sliced into voxels according to Slices Per Axis value. Number of voxels = slices per axis ^ 3.
    Step 2: If number of voxels is greater than Voxels Limit, the closest voxels are welded together to reduce their number to meet the Voxels Limit restriction.

    [​IMG]
    Here we have a simple convex object with 2 slices per axis => 2*2*2=8 voxels. 8 different forces are applied on those voxels.

    [​IMG]
    Here it is a pretty complex concave object and we need small enough voxels to reproduce the object's shape correctly. 8 slices per axis gives us 8*8*8 = 512 small voxels, but 512 different forces is far too many from performance point of view. To reduce the final number set Voxels Limit to something much less than 512, but high enough to preserve the object's behavior.

    Could you show the picture?

    Slices per axis = 4 (2 would be enough)
    Voxels limit = 4
    [​IMG]

    On the left there is a box with native size 2x4x8 - everything is fine.
    On the right there's a standard cube scaled to 2x4x8 - there's a problem, but still not that one you've described.
     
    Last edited: Jan 23, 2011
  32. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,428
    Regarding 1 and 2: I guess I don't understand why you need to calculate the density of the object. Density is defined as mass divided by volume (density = m / v), so all you should need to do is calculate the volume of the object that is immersed in water. The mass is already given in the rigidbody settings. The force that keeps a floating object level is calculated like this:
    $buoyancy.jpg
    Where the center of gravity is the center of mass and always points down, and the center of buoyancy is the center of the volume of the object that is under water. When an object tilts, the two forces work in opposite directions and that lever arm causes the object to return to level.

    What I did was I modified your script so that I can place the center of gravity (center of mass) in the inspector. In a homogeneous object, that center will be the center of the volume (what your script calculates). But for something like a boat (that has all its heavy metal items at the bottom) the center of mass will be somewhere near the bottom.

    As for the slices/voxel thing, here's a screenshot of an "extreme" example. Here's a simple cube and I've set the slices to 5 and the voxels to 27. Why 27? I have no idea. :p I would have thought that it should be 25 or 15, but those gave me an uneven number of vector gizmos so I experimented with it. ;)
    $Capture3.JPG
     
    Last edited: Jan 23, 2011
  33. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,304
    Buoyancy force depends on volume. Previously I took the total volume as a half of the object's bounding box, then I calculated the density just to print it out in debug message.

    Then I decided, it would be more clear and accurate to specify the density explicitly and to calculate the volume from that density. So now buoyancy force depends on the density you specify, and doesn't depend on the object's actual volume.

    Actually I don't use center of buoyancy. Tried to, but that was no good. Instead of calculating the exact center of buoyancy and apply buoyancy force to it, I apply local force to each voxel that is under the water and let the physics engine summarize the forces. I believe it would do it more efficiently.

    Just set Slices Per Axis = 3, and you'll get the same 3*3*3=27 voxels, but more evenly distributes. Even 2 slices and 8 voxels might be enough for that kind of shape.
     
    Last edited: Jan 23, 2011
  34. Antitheory

    Antitheory

    Joined:
    Nov 14, 2010
    Posts:
    549
    Heh, sounds like you guys are still having fun with the buoyancy script.

    I've gone a little crazy with making this script as realistic as possible, here are some additions:

    1. Calculate voxels at high-resolution (like 300,000 of them) and then downsample this to maybe 128 voxels. (this keeps your volumes very accurate and properly distributed without the need to calculate lots of forces/water heights)

    2. Calculate "wetted area" of object to determine it's drag as it moves through the water. I did this by creating many 2dimensional projections of the object at different angles, to get the surface area and surface angle.

    3. Use the surface angles (relative to the velocity through the water) to create planing affect on boat hulls and other object.

    Combined with a flying script (which analyzes wings to create lift equations) I know have a fully functional sea-plane which can land and take off on the ocean. Once it's all done I will post it in the showcase.
     
  35. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,304
    Sounds impressive!
     
  36. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,428
    Yes, that does sound good. I, in the mean time, have also taken on the task of writing my own buoyancy script. Can't have enough of them, eh?
     
  37. coco88

    coco88

    Joined:
    Mar 8, 2011
    Posts:
    4
    Hi... i am new to unity, i realize that your buoyancy script is in cs. do u know where i can get this script but in JavaScript form? cause i am using JavaScript and can only understand cs a little bit.
    Thanks for your help.
     
  38. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,304
    Unfortunately I know a little about JavaScript and can't translate the script into that language.
     
  39. SimonAlkemade2

    SimonAlkemade2

    Joined:
    Feb 4, 2009
    Posts:
    432
    this is giving me a great idea for a game :D
     
  40. Anthony85

    Anthony85

    Joined:
    Mar 9, 2011
    Posts:
    30
    Hi folks, new guy here :p, i'm sort of a new comer to unity, I've had it on my system for a while, since v2.6 i think, but never really dabbled with it, i'm just starting to take a closer look. This looks like a very good script. :) I'm definately going to try it. :) I've been wondering how to implement bouyancy in unity for a while now. Though i'm not really a coder (the best i can do is xml and html, and a bit of css. Only limited knowledge/experience with java and C#), i'm more of a modeller, and to a lesser extent, texture-er, and to an even greater lesser extent, animator :p

    But if I ever manage to coble something together in unity, and use this script, i will definately credit you :)

    I'm actually quite surprised Unity doesn't already have buoyancy features built in.
     
    Last edited: Mar 10, 2011
  41. cemC

    cemC

    Joined:
    Dec 23, 2010
    Posts:
    214
    Eureka Eureka :) Good work, i like it :)
     
  42. nevaran

    nevaran

    Joined:
    May 21, 2010
    Posts:
    218
    why does this reminds me like the source engine water effect from half life 2... :p
     
  43. soapstar

    soapstar

    Joined:
    Apr 4, 2011
    Posts:
    56
    Hey everyone this is my first post, please forgive me if this is in the wrong place! :D

    I have been following this thread and i am very intrigued by it, superb work! However since i am a complete beginner for the life of me i cant get this buoyancy script to work for me, my cube seems to 'float' or hover in the air?! Even though it is not touching the water?! Its nothing like the logs in the video! :)

    If anyone can maybe help me out with this would be great! Even just a quick example file i could download, im sure i could work it out from there!

    Thanks for any help :D
     
  44. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,304
    Raise your water to Y=0.0 level. Or change the body of the function float GetWaterLevel(float x, float z) according to what your real water level is.
     
  45. soapstar

    soapstar

    Joined:
    Apr 4, 2011
    Posts:
    56
    Hey big thanks for your help. That worked. :)

    Is there any way in which i could control the force on my object so i can change the depth at which it is buoyant? Like a submarine i suppose!

    Thanks for the help!
     
  46. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,304
    Change the object's Density property:

    ― if the density is less than 1000, the object will float;
    ― if greater than 1000, the object will sink;
    ― if equals to 1000, I guess the object should keep the depth you place it on (didn't test it actually).
     
    Last edited: Apr 5, 2011
  47. Reanimate_L

    Reanimate_L

    Joined:
    Oct 10, 2009
    Posts:
    1,931
    Is this script worked with water3?
     
  48. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,304
    Don't know actually. I took a quick glance at water3 and decided to stay with community ocean script.
     
  49. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,428
    @rea - Should work, I gave it a try when 3.2 first came out, although like alexzzzz I'm also sticking to the community ocean project.
     
  50. Reanimate_L

    Reanimate_L

    Joined:
    Oct 10, 2009
    Posts:
    1,931
    Nope...didn't work...i've just tested it.......
    Water3 it's good Imo, well you just need to modified the shader and the script to make it work correctly, and the underwater effect looks nice with screen space fog.