Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Buoyant - Buoyancy toolkit for Unity

Discussion in 'Assets and Asset Store' started by Nymisu, Apr 8, 2015.

  1. Nymisu

    Nymisu

    Joined:
    Feb 17, 2015
    Posts:
    13
    Hey everybody!

    I recently released my little buoyancy script Buoyant on the Asset Store, and i thought i should probably explain what it is, and what it does outside of the sales blurb, although the web player demo should give you a decent idea!



    It's a simple, performance efficient (this means hundreds of objects are perfectly okay) buoyancy script that easy to set up and (hopefully) easy to work with. It works with multiple levels of water, attaches to the buoyant object, but is open source so if you prefer, you can just have the water apply Buoyant to the object entering it instead with only a value or two changed from default settings to completely change the object's behavior.

    I should note that the design principle is performance and affordability first, so if you're looking for simulation-level accuracy, i would say you're better off with fully comprehensive liquid physics modules like the amazing Triton.

    It is, however, capable of providing relatively accurate buoyancy simulation with higher accuracy settings in place, and looks very fancy with waters that report their wave height accurately (the non-mobile version of Unity community Ocean, for instance)

    The idea of this thread is a 4 prong one, i'd like to:
    - Hear criticism, including the pricing and presentation. (Though i'm not very good at 3D modeling!)
    - Provide support for usage, or modifications (since it's open source instead of baked DLL)
    - Any bug reports, et.c.
    - And of course, bring awareness to my little script.
     
    Last edited: Apr 8, 2015
  2. twobob

    twobob

    Joined:
    Jun 28, 2014
    Posts:
    2,058
    I can't run your demo, just errors out

    upload_2015-4-8_12-14-32.png
    So this is a buoyancy add on for water4? (and similar), I was hoping to see how you handled the "waves displaced mesh" problem. There are no details of how it figures out it's depth, do I need to add layers? Can it follow waves regardless of the waves generator used?

    Cheers, looks interesting.
     
  3. Nymisu

    Nymisu

    Joined:
    Feb 17, 2015
    Posts:
    13
    Huh. That's very weird. I just asked a workmate to pull it up and it worked fine... maybe the hosting server had a hiccup or something akin to that. Try again with ctrl+f5 on the webpage :) If the error persist, i'd like to know the details to see if it's anything i can fix!

    It works with any water, including the completely flat planes of simple daylight water, well, in fact it doesn't even need the water per se to work, as you can tell it "assume there is water at this Y height", or just float it on a trigger. Water4 is absolutely beautiful, the problem is that the out-of-the-box version of water4 can't report wave height, which is necessary for this script to follow the wave deformations of the mesh. There seem to be ways to go about implementing this, though.

    The way it works is that it slices the volume of the collider into "voxels", except it doesn't create the voxels, just points of floatation, and then it shares the floatation capability across those points. The fewer there are, the cheaper it is, but also the stronger each point is (which can lead to -very- aggressive straightening on longer, flatter planes without modifying how many slices there are).

    The base function of the floatation algorithm is same as Alexzzzz's excellent interpretation here. I've based the most basic underlying functions on the same concept and the way he implements it, since it seems it's the only one that makes a lot of sense on object-based low-overhead buoyancy, but i've expanded the functionality, and optimized the performance notably among adding a lot of functionality, like support for multiple levels of water et.c. et.c.


    On a note:
    What it can't do yet, is understand where the waves are coming from, and move the object according to their direction. I could work this in with community Ocean for instance very specifically, but i don't want to go specific attention to one of the very many water implementations, as implementing things like that is relatively simple.
     
    Last edited: Apr 8, 2015
  4. twobob

    twobob

    Joined:
    Jun 28, 2014
    Posts:
    2,058
    (hint, I am more interested in knowing if I am underwater reliably than simply "where the surface is", of course this is the same data...) It seems you are hinting/saying that this package - in no way - actually works out where the surface /is/ it provides realistic "buoyancy" faux-physics when passed this data?

    Also. I own suimono (and a bunch of other water resources) and have looked/used those other community packages you cited in the past.. I will pay the money to check out if your implementation works with these things.

    I do, however, need to know two answers before making that choice

    a) if if can't handle the deformations of waves in water 4 - seemingly currently not - is there a "recommended" Best-Results "complete solution" and do you have some metrics please for performance. that includes surface waves.

    e.g. "Use it with Community Ocean on Unity 5_0 with version 1.0 of my script you can expect no more than 2ms performance drop on an average desktop machine, 5ms on mobile, even when working with complete screen fulls of ocean and 5 buoyant objects"

    b) it is totally garbage free. Without this being the case it simply won't be used or I will end up fixing it. Which I am tired of doing now.

    Many thanks
     
  5. Nymisu

    Nymisu

    Joined:
    Feb 17, 2015
    Posts:
    13
    The script doesn't specifically know whether or not you're underwater, but it's trivial to implement with how its waterdetection works. It knows whether or not it has touched the water, and it knows the Y level of that water at the coordinates of its floatation points. This is how it detects waves using the community ocean's script.

    It needs to do this anyway so that you don't need to make a trigger as deep as the water itself. The question of how deep you would be is simply the difference of the point in question and the water's Y level :) I know of Suimono's very beautiful water, but i do not know specifically how their water functions, and what it reports.

    a) The complete solution what you're looking for depends on what you're searching. The absolute cream of the crop would be Triton, which to my understanding comes with its own buoyancy. However, it is prohibitively expensive to some projects, both in terms of performance and money. I can vouch that my buoyancy script works with Unity Community Ocean, and even has a commented-out implementation for it. Since community ocean is free, and the aforementioned community buoyancy script is too, i recommend trying those two together to see if the results are anything like what you'd want out of it. There's currently no optimized solution between shifted wave heights to "flat plane" interpretation of water, as the differences in optimization were neglible at best ( ~0.1ms difference on 200 objects)

    The actual test:
    Given that my work machine is the slightly above-average gaming rig (AMD A-10-7800, Geforce 750GTX):
    Test environment: Standard setting Water4 32 tiles large, Unity 5.0.0f4 Personal

    Objects: 10 1x1x1 boxes, 5 2x1x1 boxes, 7 unity spheres all with Buoyant and rigidbodies.

    Buoyant on standard settings except for 1 slice amount for spheres (the only thing that works well for spheres, outside of doing literally hundreds of points) using a water trigger collisionbox(more expensive) instead of a base level water.
    http://i.imgur.com/fk8iZgU.png
    Now with 5 times the amount of objects:
    http://i.imgur.com/Yn9CYFc.png

    Mobile performance test i'm unable to give today, as i personally don't own an android or IOS mobile, but i can arrange it for tomorrow if you're interested in that specifically.

    This is with 1.0 of Buoyant script.

    b) I'm afraid you need to be a bit specific here. If you mean it won't cause nullreference exceptions, spam you with warnings or the like, then i've covered pretty much all the bases on that regard. It's actually one of the requirements for being on asset store nowadays.

    EDIT:
    Let me fetch community ocean and do a quick test on that.
     
    Last edited: Apr 8, 2015
    twobob likes this.
  6. twobob

    twobob

    Joined:
    Jun 28, 2014
    Posts:
    2,058
    b) as in it doesn't shove out any heap stuff to the garbage collector once it has started up (start-up garbage is fine)


    That was a great answer to a) by the way. (I will test it on android for you)

    upload_2015-4-8_14-44-13.png
    Also, still can't get the site working :\ hmm.. I'll try yet another machine

    (Assuming you built your demo, with pro, and with debugging enabled, and I could /access it/ I could answer the run-time garbage question myself)
     
    Last edited: Apr 8, 2015
    Nymisu likes this.
  7. Nymisu

    Nymisu

    Joined:
    Feb 17, 2015
    Posts:
    13
    Well, unfortunately i only have ~2 years programming behind me, and none of it in C++ or similar languages so handling garbage is quite an alien concept for me. I don't notice it leaking memory-wise on even absurd stress-test scenarios with literally thousands of buoyant objects, or scene-changes for that matter.

    I intended to provide a community ocean test too, but apparently the latest community ocean does not like Unity 5's d3d11_9x, complaining of missing semantics and the like. I'm not well versed in shaders enough to fix that, but it's something i can ask about tomorrow when the game studio's shader-fluent person is in to get that tested in too. I don't have 4's pro version on my seat, but i can see about doing a quick build on the pro seat we have tomorrow too. Unfortunately, the day's drawing late so i can't manage to get that done today.

    As for why it's not downloading properly, i can't even fathom a guess. Let me toss it on dropbox and see if you have better luck getting it from there... (link in a couple of minutes)

    EDIT:
    Here's the dropbox folder. Couldn't figure out a way to trick my way through actually running it on dropbox without pro. Built in unity 5 with debug settings on https://www.dropbox.com/sh/3zo4yzpzvl4va1o/AADr_kwrWcb9Sm_BYwMpaod_a?dl=0

    Edit2:
    Fixed issues. The beachballs look a bit dull without their specular, but this is the back-up plan anyway.
     
    Last edited: Apr 8, 2015
  8. twobob

    twobob

    Joined:
    Jun 28, 2014
    Posts:
    2,058
    6.3 kb per frame - with spikes of 9.4kb now and then.
    upload_2015-4-8_17-32-8.png

    which equates to 315 kilobytes per sec, 18.9 mb garbage per minute. (not including spikes)

    You can see in the example frame above that the Camera.Render + FixedUpdate takes over 30ms (not including any other overhead), and more specifically the FixedUpdate takes about the full time for single 60fps frame on it's own.

    This doesn't leave me much room for a game on top.
    I love the thing and would certainly be interested on the understanding that you remove that garbage overhead, which I am guessing will magically make those frames much shorter anyway and certainly make the running less lumpy.

    It will also make this suitable for mobile, which currently is precluded by the heap overhead.

    Excellent work, all of these points I have made are moot on a reasonably perfomant PC and this is perfect for those types of situations.

    Many thanks. Will certainly be looking to see if you iterate on this.
    (the Minimum Optimisation in my sigi is not a terrible read)
     
    Nymisu likes this.
  9. Nymisu

    Nymisu

    Joined:
    Feb 17, 2015
    Posts:
    13
    Thanks for the criticism and the mobile test, this is exactly what kind of thing i'm looking for!

    I'll work a bit on the garbage collection today according to the links you gave me, let's see in a couple of hours what i have cobbled together on the garbage collection front. It'd be nice to have it run fine on mobile too, considering the priority is performance afterall.

    EDIT: First draft pretty much halved those garbage collection numbers, and there were other optimizations too. Now it's 6.2kb spikes with 3kb garbage collection, still working on it, though. It's reporting 30B of garbage/object / frame. I'm trying to find out where that 30B is coming from, because bizarrely, not all objects have that.

    Additionally, i made some performance tweaks, such as caching certain components properly, including transform.
     
    Last edited: Apr 9, 2015
    twobob likes this.
  10. Nymisu

    Nymisu

    Joined:
    Feb 17, 2015
    Posts:
    13
    Well, this deserves a new post. I'll put version 1.1 for evaluation today.
    I took out the trash :cool:. Turns out a rather rampantly placed foreach loop was churning out all of it, huh, always thought them being more performance efficient to for loops, shows what i know.

    Also, the test scene seems to be more expensive to render than the scene with 32 water4 tiles. It's possibly my renderqueue tricks of turning simple daytime water into transparent, as i didn't have water4 when i initially made this.
    The UI is churning garbage, i'll see if i can kick that a bit lower too. It's just the way it counts the objects that causes this.

    Uploading dev build now, here's a sneakpeek of profiler:
    http://i.imgur.com/FmTgEBQ.png

    EDIT:
    Here's the garbageless build
    https://www.dropbox.com/sh/zbcvimed3p42m3z/AACj_EzxIWcrWtZ1h_W0sE1da?dl=0
    Changelog:
    Garbage collection and performance update!

    Buoyant has become green-concious, and now produces 0B of garbage, instead of 44B for each object per frame on average. This should make it viable on mobile.Thanks to twobob for helping me on this!

    Performance tweaks which increase performance up to 35% with slightly higher memory footprint stemming from caching transforms and rigidbodies of Buoyant gameobjects.

    Performance tweaks with many loops, and ifs in addition to the above.

    Bugfixes:
    Fixed a typo causing low mass (<300) objects with masscompensation on behaving very strangely.
    Please keep in mind masscompensation is still an alternative measure, your object may work better with it, or it may work worse. It's a case of "this feels better with masscompensation on".

    PS. I still don't understand why you can't open the webplayer, i tested it at home and at a friend's place yesterday. I'd love to hear if anyone else is having issues with opening it.
     
    Last edited: Apr 9, 2015
    twobob likes this.
  11. twobob

    twobob

    Joined:
    Jun 28, 2014
    Posts:
    2,058
    "I still don't understand why you can't open the webplayer"
    Me neither.

    I mean I develop FOR the webplayer all the time, and open many during the course of my day.


    Hey ho. We got there.

    Much better looking product all round. Win win for everyone.
     
    Nymisu likes this.
  12. Nymisu

    Nymisu

    Joined:
    Feb 17, 2015
    Posts:
    13
    Once again, thanks a lot for the help :) I'll keep a closer eye on garbage after this! (and avoid foreaches in update like the plague, they're apparently quite the pollutors)

    It may not be that much on gaming PC, but it all adds up afterall.
     
  13. mcmorry

    mcmorry

    Joined:
    Dec 2, 2012
    Posts:
    580
    Hi, the web player is working for me on Firefox on Mac.
    I'd like to know if this plugin is suitable for my scope:
    1. Can you increase the mass of an object to make it sink?
    2. Also how it will behave with multiple rigidbodies connected by joints? (I have a car with the wheels connected by joints)
    3. The target is mobile for a 2.5D side-scrolling racing game. And we plan to have some ice planes where the car could drive over, but sometime should also happen that the car will move them away and will enter in the water. Then the player will have to drive on the ground under the water. Do you see this feasible with your plugin.
    Thank you
     
  14. Nymisu

    Nymisu

    Joined:
    Feb 17, 2015
    Posts:
    13
    Hello! Lots and lots of apologies for my lateness. I've been way busy lately and kind of dreaded someone messaging me when i was unreachable, argh!

    Anyhow, to address your questions as well as i can:
    1) Short answer: Yes, but you can also reduce its buoyancy on the fly!

    Long answer:
    There are 2 separate ways to make an object sink. Mass increase is perfectly acceptable way to make something sink, and it works very realistically in a 'flooding' type scenario. I actually toyed around in testing with a cannon that imparted extra mass to an object to make my floating objects sink, and the end product is actually quite realistic and believeable.

    The other way is simply to reduce the buoyancy of an object. This is the way a pontoon craft would sink, for instance. Or a great way to make a submarine neutrally buoyant. Sometimes this is a better option if you're doing something else with the rigidbody's mass!




    2) Short answer: It will treat the car and the wheels as separate entities, each will require its own script.

    Long answer:
    I intentionally programmed Buoyant so that it does not count the buoyancy of child parts (as its focus is object specific buoyancy), as otherwise triggers and other colliders are calculated within the buoyancy. It's possible to tell it to only feature a singular collider, or all the collider siblings (in case of compound colliders made of primitives) to be calculated into the buoyancy calculation!

    You can put separate Buoyant scripts on the wheels, as well as adjust each script's individual in-water drag and angular drag to give a more realistic appearance. (For instance, car wheels going through the water would have comparably small in-water drag compared to the whole body!)

    I do not see the possibility of joints producing any kind of problems here specific to the buoyancy script, they can be quite temperamental at times in my experience, though!



    3)Short answer: Certainly!

    Long answer:
    Yes! Though for added utility, in my experiments, to have "object on buoyant object"-scenarios work better, since there's a lot of 'cheating' going on programming wise, you might want to devise a script that adds mass (or reduces buoyancy, as discussed in 1. question!) to the buoyant ice plane you'd be driving on to make it dip lower when the car is passing over it. It will still dip and turn, but in my experience adding mass or reducing buoyancy helps it look better.

    If you message me via email ( impendingfeaturecreep ((at) gmail) we can probably work together with some sort of examples or i can toss you a free sample/demo of the script in case you're still interested despite my tardiness! :)
     
    Last edited: Jan 5, 2016
    mcmorry likes this.
  15. The_Geoff

    The_Geoff

    Joined:
    Mar 22, 2014
    Posts:
    7
    Hi Nymisu,

    Thank you for this excellent asset! Just set it up to work with Ceto Oceans in about 5 minutes. Excellent documentation :)

    I am currently attempting to use the buoyancy toolkit in a naval simulation and I've run into a couple of problems - I was hoping you could give me some advice.

    The idea was to model each ship as a collection of buoyant objects connected to a central "ship" object using fixed joints. So for example, a large ship could comprise two rows of four buoyant cubes, all attached to one central rigidbody. If the ship is damaged and starts taking on water in one area, I would increase the mass of the cubes in the affected area so that the ship tilts and begins sinking in an accurate manner.

    My problem is that the ships never fully sink! No matter how heavy the damaged cubes become, the undamaged ones always keep the ship afloat. Even if every cube has enough mass to pull it underwater, the ship will not sink to the bottom - it sort of hovers just under the surface of the water. Each buoyant object is marked as "sinkable", and I've even tried manually setting "alreadysinking=true" but no luck. I would really appreciate any adivce you may have on how to get this working.
     
  16. Nymisu

    Nymisu

    Joined:
    Feb 17, 2015
    Posts:
    13
    Hello, there and thank you for the kind words!
    I'll do what i can to help. Do apologize the 2 day's delay though, new job (well, more of an assignment), new level of busy! (That and XCOM2 came out. *cough cough cough* )

    That sectioned idea does sound very interesting, i will have to do some personal testing around it! The katamaran-type ships in this thread's webdemo (2 pontoons, one central boatshape) use 3 buoyancy boxes, even if the screenshot given uses meshcollider as an example. That's sort of all well and good, since Unity 5 whines about using meshcolliders for physics objects.

    I... have named that boolean confusingly in my coding frenzy. Toggling alreadysinking only affects line 518:
    Code (CSharp):
    1.             if(sinkable && !alreadysinking)
    2.             {
    3.                 SinkableHandling();
    4.             }
    It's just telling the script that "you have handled SinkableHandling's if state once already".

    Under SinkableHandling method, you'll find this if state:
    Code (CSharp):
    1. if (ownrigid.mass > originalmass * (1 + (percentagedifference / 100)))
    What you may want to change is the "percentagedifference" on all the Buoyant scripts attached to say, -10.
    The percentagedifference doesn't affect the sinking process in any way, so it's safe to just tell it to "sink if your mass is practically anything, because the ship should be sinking".

    The sinking state assumes that the ship has gone beyond its sinking threshold, and only moves the center of mass to unbalance it, so you will need special handling for that.

    You will also, however, need to call sinking states in some way on the other scripts attached to the ship and handle them.
    Probably easiest if you just make a tiny script which holds all the Buoyant scripts on the single ship in a list so they can be called/told what to do at will.

    Alternatively, and probably a better solution in any case, make another public boolean and modify the 692 line onward like so:
    Code (CSharp):
    1. public bool MakeItSink = false;
    2. (.........)
    3. //Line 692 below.
    4. if (ownrigid.mass > originalmass * (1 + (percentagedifference / 100)) || MakeItSink ){
    5.     if(MakeItSink) {
    6.     //Make a mass-adding algorithm here, OR alternatively change density above 1000
    7.     //more if mass compensation is on, and run the following lines:
    8.     density = 1100; //+ added factor for faster sinking
    9.     //The next bit is copied from EditingValues if state. It's required for density adjustment on the fly.
    10.     floatvolume=ownrigid.mass/density;
    11.     floatarchimedesForceMagnitude=WATER_DENSITY*Mathf.Abs(Physics.gravity.y)*volume;
    12.     localArchimedesForce=newVector3(0,archimedesForceMagnitude,0)/voxels.Count;
    13.     }
    14. (......)
    Also, you might want a new handling for the sink-states, since the sinking algorithm currently has a set direction it sinks in. Grab the position of the most damaged part of your ship, and modify the algorithm to move the center of mass toward that direction, but first you may want to just try disabling the multipliers and see how it does on its own. It might be enough to just place the center of the mass on the coordinates of the most damaged portion of your ship :)


    As a little bonus mention, since you're using that many cubes, you may experiment with lowering the amount of Buoyancy points of those cubes in the slicing options. Try 1, 2, 4 and 8 instead of the default. It should give you (somewhat minor) a performance boost... or it could cause the physics to completely throw a hissyfit, amusement either way! :)
     
    Last edited: Feb 9, 2016
  17. The_Geoff

    The_Geoff

    Joined:
    Mar 22, 2014
    Posts:
    7
    That's very helpful, thank you! I'll give it a try and let you know how it goes.
     
  18. Nymisu

    Nymisu

    Joined:
    Feb 17, 2015
    Posts:
    13
    Thank you for the review, i'm very happy that you found my script useful and got it to do what you wanted it to do! :)
     
    Last edited: Feb 22, 2016
  19. John-G

    John-G

    Joined:
    Mar 21, 2013
    Posts:
    1,114
    Getting a few errors with the BuoyantEditor.cs script, no biggie but would be nice not to have them every-time I run. ;)

    Assets/Buoyant/Editor/BuoyantEditor.cs(98,49): warning CS0472: The result of comparing value type `UnityEngine.Rigidbody.centerOfMass' with null is `false'

    Assets/Buoyant/Editor/BuoyantEditor.cs(99,17): warning CS0162: Unreachable code detected

    Assets/Buoyant/Editor/BuoyantEditor.cs(124,39): warning CS0618: `UnityEditor.EditorGUILayout.ObjectField(UnityEngine.GUIContent, UnityEngine.Object, System.Type, params UnityEngine.GUILayoutOption[])' is obsolete: `Check the docs for the usage of the new parameter 'allowSceneObjects'.'
     
  20. Nymisu

    Nymisu

    Joined:
    Feb 17, 2015
    Posts:
    13
    Hi, thanks for the heads up!

    I'll try and squeeze an update in today, which will address at least the first two.

    The third one is, from where i'm seeing, a Unity 5 specific errormessage, because this is a 4.5.1 release so it uses newly obsolete code like that.

    I'm somewhat unsure at the moment if i want to push it as Unity 5 upward as that might break some backward compatibility things with Unity 4.5, and this doesn't really use any Unity 5 specific code or assets.

    Unfortunately no part of the sales data mentions which Unity version it would be used for, so i'm working on complete unknown on how many people might be using it under Unity 4, and how miffed they would be if i nudged it up one version :p
     
  21. John-G

    John-G

    Joined:
    Mar 21, 2013
    Posts:
    1,114
    Belive you can upload a unity4 and a unity5 version to the asset store, it's recognise which version the user is using to download appropriate version.
     
  22. Nymisu

    Nymisu

    Joined:
    Feb 17, 2015
    Posts:
    13
    It should be available now, or at least soon(tm), when the draft goes through. Apparently i screwed up the first upload on 22nd (somehow a dumb tiny fix took me so long, sorry!) somehow and it didn't appear in the drafts.

    You were right on the separate versions, though! I did not know of the separate packages, probably something i missed in the flood of policies and whatnot.

    You won't get a new version update notification... i think. I didn't update it with the new version, since it's literally just changing a few lines in one file.



    I did do some extra experimentation for a proper little version update too, to get a nice gizmo working for the centerofmass shifting and some additional bugfixing on a particularly annoying bug i know about that, but something in the maths in modifying that sort of a thing just i don't get right. It's the difficulty of getting the rotation along with the positioning, and i just can't manage to get the hang of it. I must've tried a good dozen different things this week alone, so unfortunately i wasn't succesful in that. I'll keep trying on that front when i have free time to experiment with new features that would be neat.

    I'll welcome any suggestions for fixes and improvements too, of course!
     
    John-G likes this.