Search Unity

  1. Are you interested in providing feedback directly to Unity teams? Sign up to become a member of Unity Pulse, our new product feedback and research community.
    Dismiss Notice

Buoyancy script

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

  1. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,434
    It definitely should work. The only thing you need to do is to change the name of the variable for the water height from the shader. I'm like 95% sure I got it to work. I'm in the middle of something at the moment otherwise I'd dig it up and fix it myself.
     
    Last edited: Apr 5, 2011
  2. immFX

    immFX

    Joined:
    Mar 20, 2010
    Posts:
    110
    I confirm that it works with Water3, bigkahuna is right :)
    Just assign to gameWater your Water3, and:

    private float GetWaterLevel(float x, float z)
    {
    return gameWater.GetHeightOffsetAt(transform.position).y;
    }
     
    Last edited: Apr 7, 2011
  3. Reanimate_L

    Reanimate_L

    Joined:
    Oct 10, 2009
    Posts:
    2,528
    Okay confirmed...it's works nicely..thanks guys
     
  4. freamzeed

    freamzeed

    Joined:
    May 11, 2011
    Posts:
    1
    Thxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
     
  5. ognjenm

    ognjenm

    Joined:
    May 3, 2011
    Posts:
    97
    my eng is bad, so i cant figure out this ??
     
  6. nopcode

    nopcode

    Joined:
    Apr 29, 2011
    Posts:
    60
    I'm not able to get your Buoyancy.cs to work with the community ocean example - it complete ignores the waves and pretty much just "does its own thing". Can you post the example you have from the video?
     
  7. ipe369

    ipe369

    Joined:
    Jun 19, 2011
    Posts:
    6
    Is this using the pro water? And also, how do you make yourself float? do you add a rigidbody and the script to the firstpersoncontroller prefab?
     
  8. mojojojo

    mojojojo

    Joined:
    Dec 16, 2009
    Posts:
    138
    I attached this script to a box (w/ box collider replaced w/ a mesh collider) and it falls but then rocks uncontrollably and eventually flies off into spaces while rotating. Do you know what I may be doing wrong here?
     
  9. Moon

    Moon

    Joined:
    Apr 19, 2011
    Posts:
    40
    I'm horrible at C# .. This isn't working for me =/ ...How do I get it to work? Does it work with non-pro Unity?
     
  10. madpuppy

    madpuppy

    Joined:
    Sep 8, 2011
    Posts:
    2
    this is my first post, so hello everyone :)

    i am having a similar issue with waves and this script as nopcode above: after the object is at the global water level, it is not moved anymore by the water, ie. it ignores waves completely. do you need to change the boyancy script to get it to work or is it something else that i missed?

    btw: this community shader is awesome!!!

    just checked out the community boyancy script and there i assign the ocean.js/cs to the boyancy script, which is missing here?

    EDIT: Found it! Two lines (as said before by bigkahuna) in the boyancy script that refer to ocean script were commented out. just undo that and it rocks the waves!
     
    Last edited: Sep 8, 2011
  11. HaVaNa7

    HaVaNa7

    Joined:
    Dec 23, 2011
    Posts:
    44
    Hi to all, i would like to make a simple scene where a boat is floating on the ocean, and a character can walk over it, can someone show me an example? I 've tried with boyancy community script but when i walk on the boat it goes crazy... is possible also to stop water to came inside the boat?

    Thnx
     
  12. omarzonex

    omarzonex

    Joined:
    Jan 16, 2012
    Posts:
    158
    very nice man

    beautifull script water realistic physics
     
  13. darmie

    darmie

    Joined:
    Sep 13, 2012
    Posts:
    3
    Can I use this script without Water? I mean I want objects to float in air!
     
  14. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,444
    You can.

    Code (csharp):
    1.     private float GetWaterLevel(float x, float z)
    2.     {
    3.         return 0.0f;
    4.     }
    5.  
    Change 0.0f to whatever height you want.
     
  15. codeshiri

    codeshiri

    Joined:
    Oct 22, 2012
    Posts:
    1
    Hello Guys ,I am working now to my games River Surfing , I have a option to get coin , my problem is I cannot get float the coin in water ,i am using Buoyancy Toolkit but I cannot float the coin ,then I try the script by alexzzz,But its not working for me ,please help me .

    EDIT: its has rigidbodies and collider in coin
     
    Last edited: Nov 6, 2012
  16. dansav

    dansav

    Joined:
    Sep 22, 2005
    Posts:
    462
    Could you explain how it works in layman terms.
    I think it's taking a mesh collider then marking a set of points in x,y,z axis.
    If the point is inside the collider it becomes involved in the buoyancy calculations.
    If the point is outside then it is ignored. Somehow it creates a volume from these points.
    Then it computes the center of buoyancy of the volume underwater vs the center of mass
    and applies forces.

    Something like that?

    Does it require a mesh collider to be on the object.
    Don't mesh to mesh collisions have problems.
    Thanks for making the script public.

    Dan
     
  17. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,444
    Does it move up or down?

    Make sure that the function GetWaterLevel(...) returns your actual water level.

    Correct.

    It doesn't create or compute any volume, neither the center of buoyancy. It just applies local forces to all the points.

    Any collider is fine. But if you want your object to be treated as concave, you have to use mesh collider.

    Concave mesh colliders collide only with character controllers (UPD: and primitive colliders). Convex mesh colliders collide with everything.
     
    Last edited: Nov 17, 2012
  18. bartleycollin

    bartleycollin

    Joined:
    Aug 1, 2012
    Posts:
    88
    Very nice, I love it when people add something "Game-Changing" to unity :D
     
  19. skeptika

    skeptika

    Joined:
    Dec 31, 2011
    Posts:
    108
    Does anyone know how to get the water height in Water4? I would like to return the wave heights in Water4 to successfully bounce off the waves but don't see an obvious way to do this (there appears to be no GetWaterHeight() style function in any of the Water4 source)? Any help would be appreciated!
     
  20. Map-Builder

    Map-Builder

    Joined:
    Aug 29, 2012
    Posts:
    11
    Hi,

    I did few changes to the buoyancy script.

    1 - It's been transposed in JS (i just needed that)
    2 - It takes in count the children (except concave) physically dependent (same rigidbody) and calculate the slices according to the dimension of the child's collider own bounds (for optimisation and thin walls objects).

    View attachment $Buoyancy.js

    Just Attach it to the rigidbody

    $Nouvelle image.jpg

    [Edit : to not take care of isTrigger colliders]
     
    Last edited: Mar 4, 2013
  21. dansav

    dansav

    Joined:
    Sep 22, 2005
    Posts:
    462
    Very cool addition to add children for complex objects. I'll try it out.
     
  22. Marek_Bakalarczuk

    Marek_Bakalarczuk

    Joined:
    Dec 28, 2012
    Posts:
    102
    Can you attach C# version if you have it?
    Is there any possibility to use Simple or Advanced Water from Unity Standard Assets?
     
  23. Cocoss

    Cocoss

    Joined:
    Jun 4, 2013
    Posts:
    2
    Very good job it works correctly ! But i have some problems for using this in my game. I want to make a boat which is usable by the character. My game will be in First Person View and i want to be able to walk on the floating boat (it will be a big pirates boat). If the player want to drive this boat he just needs to walk to the helm. So my problem is : when my character is on the boat, the boat sinks. I tried to modifiy the script but it's quite hard i'm a beginner and i code in javascript and not in CS. I tried to change the mass, density etc... Somebody's got an idea ?

    PS : Sorry for my English that's not my mother tongue. ^^
     
  24. Map-Builder

    Map-Builder

    Joined:
    Aug 29, 2012
    Posts:
    11
    1) sorry i translated it in javascript because i prefer JS so i do not have the c# version.

    2) Cocoss, i suppose that your character is not physic (so it pushes the boat without any backward reaction), you should better you a physic FPS controlle : http://wiki.unity3d.com/index.php?title=FPSWalkerEnhanced, and that's surprisingly accurate (mathematical) for physics (jump height...). That should work even if i think it's probably not a really stable thing to that (complicated).
    Mais ça peut être interressant, continu sur ta lancée ;).
     
  25. Map-Builder

    Map-Builder

    Joined:
    Aug 29, 2012
    Posts:
    11
    Last edited: Jun 21, 2013
  26. cmvrgr

    cmvrgr

    Joined:
    Feb 24, 2011
    Posts:
    20
    I have a boat with too many child objects and the free buoyancy scripts that I found is sinking (I have a hull as one object and all the other objects are as child objects) when I enable the child objects the boat sinks.

    If only the hull is enabled the boat is floating. in forums some users say that you need every child object to have a collider but this is too difficult as there are hundreds of objects.

    any ideas ?
     
  27. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,434
    Most of these scripts require objects to have a collider so they can calculate the "volume" of the object to accurately calculate their buoyancy. So to use them your objects have to have colliders.

    But there are a lot of other ways to simulate buoyancy, depending on how realistic you need it to be, including using springs.
     
  28. Jack Thomas

    Jack Thomas

    Joined:
    Jun 26, 2013
    Posts:
    34
    I must be doing something wrong, my character controller seems to flip out any floating object such as a boat. I've tried separating the collision layers and ignoring the character controller but im still able to interact with the object. I dont understand where the collision is coming from, is anywhere in the code manipulating the physics between objects or is it just the default rigidbody doing the work?

    Ive tried childing a mesh collider specifically for the player and ignoring the buoyancy mesh but its still getting collision.

    I just want to walk around a boat without it flipping upside down.
    Does anybody have a good example of a buoyant object you can physically walk around on without it going insane?
     
    Last edited: Jun 26, 2013
  29. Map-Builder

    Map-Builder

    Joined:
    Aug 29, 2012
    Posts:
    11
    In most games, they simulate buoyancy without physics.

    If your character is not physic based, that's normal, consider using FPSWalkerEnhanced which is physics based.

    Then, i advice you to parent it with your boat rigidbody and work around with frozenRotations. By parenting, if the boat is translating the child too. However, it does not take in count the momentum and if the boat rotates too fast, you could have some issue. But i think it probably the simple way to get something without having to do complex scripts.
     
  30. Hwaus

    Hwaus

    Joined:
    Mar 21, 2013
    Posts:
    13
    Hello everyone, I have been following this thread. Due to being relatively new to unity, I was wondering if someone can help a noobie set this script up. Please correct me if I am wrong. Using the following two assets, easy water and boat controller, I proceed to do the following steps?

    1. add buoyancy script to boat
    2. add ocean script to easy water

    ?

    So far I put the buoyancy script on the boat, but before I could test that, (I have not done anything with the ocean script yet) I got this error for the ocean script "The type or namespace name `ComplexF' could not be found. Are you missing a using directive or an assembly reference?"
     
    Last edited: Jul 1, 2013
  31. Map-Builder

    Map-Builder

    Joined:
    Aug 29, 2012
    Posts:
    11
    1) add an object with a collider(s) (even in children) and rigidbody.
    2) attach this script View attachment $BuoyancyJS.js
    3) set the level of water in world coordinates
    // CONGRATULATION, you got a physic object which is floating

    4) by script, use AddForce to move your object
    *) for a boat, you should have to change rigidbody.centerOfMass = Vector3 (0, -2, 0); to make it more stable
     
  32. zenforhire

    zenforhire

    Joined:
    Nov 5, 2012
    Posts:
    65
    Hi All,

    The c# script works well until my ship tries to make a circle. I have test scene for turning radius of a cargo ship.
    When Bouyancy and gravity turned on, it slows down and rolls over 45 degrees, z rotation over 45, in the first 90 degree turn.
    Without the script, makes circles without flipping over.
    Happens to all ships in my game.

    I tried looking at FixedUpdate() with no luck.
    I thought it was just adding force in the Up direction?

    Thanks,
    Kevin
     
  33. Map-Builder

    Map-Builder

    Joined:
    Aug 29, 2012
    Posts:
    11
    I modified script in JS but c# is still raw. So, the script works only with the collider attached to its gameobject. Is your boat made from different colliders which needs to float ? It could be a problem of mass. If your boat has a thin "wall"...

    Hard to say that way. need a screenshot.
     
  34. Skotous

    Skotous

    Joined:
    Oct 30, 2013
    Posts:
    1
    wow that was exactly what I was looking for many thanks :D
     
  35. Lachee_

    Lachee_

    Joined:
    Aug 5, 2013
    Posts:
    3
    I just got your script and it works perfectly for my scene, however I do not base my water of Y = 0.

    Insterad my water is a plane with a Sin wave applied to each vert. I was wondering if there is anyway to change you script around so it bases the bouyency of the mesh instead?


    EDIT: Never mind, I found out how.

    In getWaterHeight I simply called a raycast ignoring all layers except for water and based it of the hit point. If no hit point was found, I reverted to 0F;
     
    Last edited: Nov 13, 2013
  36. OJ3D

    OJ3D

    Joined:
    Feb 13, 2014
    Posts:
    33
    Hey, I get the same issue. Confused on what to do next
     
  37. odival

    odival

    Joined:
    Jun 11, 2014
    Posts:
    57
    Guys I need help. I'm novice, using Unity4 Indie and I cant, for the life of me, make this work.
    I tried this script with the community ocean (the mobile optmized version) and scrawk's ocean renderer, to no avail - I know I should edit the line 244 (the GetWaterLevel thingy) but I don't know what to change it to (considering Im using scrawk's).
    I downloaded the $ocean script in this page but it doenst work as well, because of the errors in pic1.

    I need to make this work bad! Can someone help me or mabe provide a unitypackage with a template scene?
     

    Attached Files:

  38. Yandalf

    Yandalf

    Joined:
    Feb 11, 2014
    Posts:
    466
    Lachee Domain, I'm using your idea but I think I'm doing something wrong.
    While the object stays afloat at the water mesh's original position, it does not keep track of the waves at all.
    How do you get the raycast properly masked as well? I created a layer called water, put the water in there, and assigned this as a layermask to the raycast, but unless I put the object that needs to float into the IgnoreRaycast layer (which is obviously something you don't want to do), it doesn't work.

    Another problem is that when the object sinks down to about 3 units away from the surface the buoyancy script stops working alltogether, causing the object to freefall. I seem to get this result because the Raycast fails (it reverts to 0), but since I set the distance to Mathf.Infinity, this shouldn't be a problem as far as I know.

    My code for the raycast:

    private float GetWaterLevel()
    {
    RaycastHit hit;

    Vector3 RayOrigin = transform.position + new Vector3 (0, 2, 0);;


    if (Physics.Raycast (RayOrigin, -Vector3.up, out hit, Mathf.Infinity, waterLayer))
    {
    return hit.point.y;
    }
    else if (Physics.Raycast (RayOrigin, Vector3.up, out hit, Mathf.Infinity, waterLayer))
    {
    return hit.point.y;
    }
    else
    {
    return 0f;
    }
     
  39. Neoku

    Neoku

    Joined:
    Oct 27, 2014
    Posts:
    261

    Hello, your update of this script work very fine in Unity 5 but i have a problem, after ini the buoyancy movement is less and less and after 1 min aprox. the bouyancy stop, any recomendation for make that the script maintain the movement all time?, thanks.
     
    Last edited: Mar 5, 2015
  40. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,444
    If it happend because the rigidbody falls asleep,you can set its Rigidbody.sleepThreshold to zero. Maybe it will help.
     
  41. Griffo

    Griffo

    Joined:
    Jul 5, 2011
    Posts:
    683
    Hi,

    I get an error on the line 6, the error is ..

    Operator '+' cannot be used with a left hand side of type 'Object' and a right hand side of type 'Object'.

    Anyone else?

    Code (JavaScript):
    1.                 var mixed : Vector3;
    2.                 while (list.length > targetCount)
    3.                 {
    4.                     FindClosestPoints(list); // pass by private var : firstIndex, secondIndex
    5.        
    6.                     mixed = (list[firstIndex] + list[secondIndex]) * 0.5;
    7.                     list.RemoveAt(secondIndex); // the second index is always greater that the first => removing the second item first
    8.                     list.RemoveAt(firstIndex);
    9.                     list.Add(mixed);
    10.                 }
     
  42. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,444
    I guess, list must be declared as a collection of Vector3 elements.
    Code (csharp):
    1. var list: List.<Vector3>;
     
  43. Griffo

    Griffo

    Joined:
    Jul 5, 2011
    Posts:
    683
    alexzzzz thanks for the input, list is declared at the top of the function.

    Code (JavaScript):
    1. function WeldPoints(listBuiltin : Vector3[], targetCount : int)
    2. {
    3.     var list = new Array();
    4.     for (var i : int = 0; i < listBuiltin.length; i++) list.Push(listBuiltin[i]);
    5.     if (list.length <= 2 || targetCount < 2)
    6.     {
    7.         return;
    8.     }
    9.    
    10.     var mixed : Vector3;
    11.     while (list.length > targetCount)
    12.     {
    13.         FindClosestPoints(list); // pass by private var : firstIndex, secondIndex
    14.  
    15.         mixed = (list[firstIndex] + list[secondIndex]) * 0.5;
    16.         list.RemoveAt(secondIndex); // the second index is always greater that the first => removing the second item first
    17.         list.RemoveAt(firstIndex);
    18.         list.Add(mixed);
    19.     }
    20.            
    21.     return list.ToBuiltin(Vector3);
    22. }
     
  44. Neoku

    Neoku

    Joined:
    Oct 27, 2014
    Posts:
    261
    Thanks Alexzzzz, i change SleepThreshold to 0 but not fix the problem, the buoyancy effect stop few time after start the game.
     
  45. sebeisdrache

    sebeisdrache

    Joined:
    Jan 16, 2015
    Posts:
    34
    this script works very well, thank you for this :)
     
  46. Stiffx

    Stiffx

    Joined:
    Oct 27, 2014
    Posts:
    455
    wow thank you very much. This is awesome :)
     
  47. modulo34

    modulo34

    Joined:
    Sep 13, 2014
    Posts:
    30
    Hello, i have buy a asset made with water 4, and i have try to make some cube float on water(Water4Example (Advanced), but with no succes,do there a special "trick" to make it work?

    Thank you so much!
     
  48. nevaran

    nevaran

    Joined:
    May 21, 2010
    Posts:
    247
    Heres a 5.x version guys-- i have also made it compact and with a target mesh! For those who use empty gameobjects as their root!

    Code (CSharp):
    1. using System.Collections.Generic;
    2. using UnityEngine;
    3.  
    4. public class Buoyancy : MonoBehaviour{
    5. //    public Ocean ocean;
    6.     public GameObject target;
    7.  
    8.     public float density = 500;
    9.     public int slicesPerAxis = 2;
    10.     public bool isConcave = false;
    11.     public int voxelsLimit = 16;
    12.  
    13.     private const float DAMPFER = 0.1f;
    14.     private const float WATER_DENSITY = 1000;
    15.  
    16.     private float voxelHalfHeight;
    17.     private Vector3 localArchimedesForce;
    18.     private List<Vector3> voxels;
    19.     private bool isMeshCollider;
    20.     private List<Vector3[]> forces; // For drawing force gizmos
    21.  
    22.     private Rigidbody rigid;
    23.     private Collider col;
    24.     private MeshCollider meshCol;
    25.  
    26.     private void Start(){
    27.         rigid = GetComponent<Rigidbody>();
    28.         col = target.GetComponent<Collider>();
    29.         meshCol = target.GetComponent<MeshCollider>();
    30.         forces = new List<Vector3[]>();// For drawing force gizmos
    31.  
    32.         // Store original rotation and position
    33.         var originalRotation = transform.rotation;
    34.         var originalPosition = transform.position;
    35.         transform.rotation = Quaternion.identity;
    36.         transform.position = Vector3.zero;
    37.  
    38.         // The object must have a collider
    39.         if(col == null){
    40. //            Debug.LogWarning(string.Format("[Buoyancy.cs] Object \"{0}\" had no collider.", name));
    41.             enabled = false;
    42.         }
    43.         isMeshCollider = meshCol != null;
    44.  
    45.         var bounds = col.bounds;
    46.         if(bounds.size.x < bounds.size.y){
    47.             voxelHalfHeight = bounds.size.x;
    48.         }
    49.         else{
    50.             voxelHalfHeight = bounds.size.y;
    51.         }
    52.         if(bounds.size.z < voxelHalfHeight){
    53.             voxelHalfHeight = bounds.size.z;
    54.         }
    55.         voxelHalfHeight /= 2 * slicesPerAxis;
    56.  
    57.         // The object must have a RidigBody
    58.         if(rigid == null){
    59. //            Debug.LogWarning(string.Format("[Buoyancy.cs] Object \"{0}\" had no Rigidbody.", name));
    60.             enabled = false;
    61.         }
    62.         rigid.centerOfMass = new Vector3(0, -bounds.extents.y * 0f, 0) + transform.InverseTransformPoint(bounds.center);
    63.  
    64.         voxels = SliceIntoVoxels(isMeshCollider && isConcave);
    65.  
    66.         // Restore original rotation and position
    67.         transform.rotation = originalRotation;
    68.         transform.position = originalPosition;
    69.  
    70.         float volume = rigid.mass / density;
    71.  
    72.         WeldPoints(voxels, voxelsLimit);
    73.  
    74.         float archimedesForceMagnitude = WATER_DENSITY * Mathf.Abs(Physics.gravity.y) * volume;
    75.         localArchimedesForce = new Vector3(0, archimedesForceMagnitude, 0) / voxels.Count;
    76.  
    77. //        Debug.Log(string.Format("[Buoyancy.cs] Name=\"{0}\" volume={1:0.0}, mass={2:0.0}, density={3:0.0}", name, volume, rigid.mass, density));
    78.     }
    79.  
    80.     private List<Vector3> SliceIntoVoxels(bool concave){
    81.         var points = new List<Vector3>(slicesPerAxis * slicesPerAxis * slicesPerAxis);
    82.  
    83.         if(concave){
    84.             var meshC = meshCol;
    85.  
    86.             var convexValue = meshC.convex;
    87.             meshC.convex = false;
    88.  
    89.             // Concave slicing
    90.             var bounds = col.bounds;
    91.             for(int ix = 0; ix < slicesPerAxis; ix++){
    92.                 for(int iy = 0; iy < slicesPerAxis; iy++){
    93.                     for(int iz = 0; iz < slicesPerAxis; iz++){
    94.                         float x = bounds.min.x + bounds.size.x / slicesPerAxis * (0.5f + ix);
    95.                         float y = bounds.min.y + bounds.size.y / slicesPerAxis * (0.5f + iy);
    96.                         float z = bounds.min.z + bounds.size.z / slicesPerAxis * (0.5f + iz);
    97.  
    98.                         var p = transform.InverseTransformPoint(new Vector3(x, y, z));
    99.  
    100.                         if(PointIsInsideMeshCollider(meshC, p)){
    101.                             points.Add(p);
    102.                         }
    103.                     }
    104.                 }
    105.             }
    106.             if(points.Count == 0){
    107.                 points.Add(bounds.center);
    108.             }
    109.  
    110.             meshC.convex = convexValue;
    111.         }
    112.         else{
    113.             // Convex slicing
    114.             var bounds = col.bounds;
    115.             for(int ix = 0; ix < slicesPerAxis; ix++){
    116.                 for(int iy = 0; iy < slicesPerAxis; iy++){
    117.                     for(int iz = 0; iz < slicesPerAxis; iz++){
    118.                         float x = bounds.min.x + bounds.size.x / slicesPerAxis * (0.5f + ix);
    119.                         float y = bounds.min.y + bounds.size.y / slicesPerAxis * (0.5f + iy);
    120.                         float z = bounds.min.z + bounds.size.z / slicesPerAxis * (0.5f + iz);
    121.  
    122.                         var p = transform.InverseTransformPoint(new Vector3(x, y, z));
    123.  
    124.                         points.Add(p);
    125.                     }
    126.                 }
    127.             }
    128.         }
    129.  
    130.         return points;
    131.     }
    132.  
    133.     private static bool PointIsInsideMeshCollider(Collider c, Vector3 p){
    134.         Vector3[] directions = { Vector3.up, Vector3.down, Vector3.left, Vector3.right, Vector3.forward, Vector3.back };
    135.  
    136.         foreach(var ray in directions){
    137.             RaycastHit hit;
    138.             if(c.Raycast(new Ray(p - ray * 1000, ray), out hit, 1000f) == false){
    139.                 return false;
    140.             }
    141.         }
    142.         return true;
    143.     }
    144.  
    145.     private static void FindClosestPoints(IList<Vector3> list, out int firstIndex, out int secondIndex){
    146.         float minDistance = float.MaxValue, maxDistance = float.MinValue;
    147.         firstIndex = 0;
    148.         secondIndex = 1;
    149.  
    150.         for(int i = 0; i < list.Count - 1; i++){
    151.             for(int j = i + 1; j < list.Count; j++){
    152.                 float distance = Vector3.Distance(list[i], list[j]);
    153.                 if (distance < minDistance){
    154.                     minDistance = distance;
    155.                     firstIndex = i;
    156.                     secondIndex = j;
    157.                 }
    158.                 if(distance > maxDistance){
    159.                     maxDistance = distance;
    160.                 }
    161.             }
    162.         }
    163.     }
    164.  
    165.     private static void WeldPoints(IList<Vector3> list, int targetCount){
    166.         if(list.Count <= 2 || targetCount < 2){
    167.             return;
    168.         }
    169.  
    170.         while (list.Count > targetCount){
    171.             int first, second;
    172.             FindClosestPoints(list, out first, out second);
    173.  
    174.             var mixed = (list[first] + list[second]) * 0.5f;
    175.             list.RemoveAt(second); // the second index is always greater that the first => removing the second item first
    176.             list.RemoveAt(first);
    177.             list.Add(mixed);
    178.         }
    179.     }
    180.  
    181.     private float GetWaterLevel(float x, float z){
    182. //        return ocean == null ? 0.0f : ocean.GetWaterHeightAtLocation(x, z);
    183.         return 0.0f;
    184.     }
    185.  
    186.     private void FixedUpdate(){
    187.         forces.Clear();// For drawing force gizmos
    188.  
    189.         foreach(var point in voxels){
    190.             var wp = transform.TransformPoint(point);
    191.             float waterLevel = GetWaterLevel(wp.x, wp.z);
    192.  
    193.             if(wp.y - voxelHalfHeight < waterLevel){
    194.                 float k = (waterLevel - wp.y) / (2 * voxelHalfHeight) + 0.5f;
    195.                 if(k > 1){
    196.                     k = 1f;
    197.                 }
    198.                 else if(k < 0){
    199.                     k = 0f;
    200.                 }
    201.  
    202.                 var velocity = rigid.GetPointVelocity(wp);
    203.                 var localDampingForce = -velocity * DAMPFER * rigid.mass;
    204.                 var force = localDampingForce + Mathf.Sqrt(k) * localArchimedesForce;
    205.                 rigid.AddForceAtPosition(force, wp);
    206.  
    207.                 forces.Add(new[] { wp, force }); // For drawing force gizmos
    208.             }
    209.         }
    210.     }
    211.  
    212.     private void OnDrawGizmos(){
    213.         if(voxels == null || forces == null){
    214.             return;
    215.         }
    216.  
    217.         const float gizmoSize = 0.05f;
    218.         Gizmos.color = Color.yellow;
    219.  
    220.         foreach(var p in voxels){
    221.             Gizmos.DrawCube(transform.TransformPoint(p), new Vector3(gizmoSize, gizmoSize, gizmoSize));
    222.         }
    223.  
    224.         Gizmos.color = Color.cyan;
    225.  
    226.         foreach(var force in forces){
    227.             Gizmos.DrawCube(force[0], new Vector3(gizmoSize, gizmoSize, gizmoSize));
    228.             Gizmos.DrawLine(force[0], force[0] + force[1] / rigid.mass);
    229.         }
    230.     }
    231. }
     
    John-G likes this.
  49. Monte1312

    Monte1312

    Joined:
    Sep 9, 2015
    Posts:
    5
    Hey guys, I've just started seeing this thread, I'm developing a simulation about a boat that makes bathymetry, and I'm controlling it with an xbox controller. My question is, I've just started using the buoyancy script Nevaran commented and it works, I put it to a cube and I'm using the simple water that comes with Unity pro, but when I, for example, change the wave amplitude the cube stays the same, is not changing it's buoyancy veolicity or something like that, and I assumed it had to change.
    I appriciate if anyone can help me with this, I'm not that newbie but i suck at programming.
    Thanks.
     
  50. NullSignal

    NullSignal

    Joined:
    Sep 18, 2013
    Posts:
    45
    Just tried to use this and it makes my ship endlessly fly into the sky. What does the target need to be? Will an empty gameobject with a boxcollider where I want the ship to float be incorrect? That's what I'm currently trying to use and, yeah, the ship just flies up.
     
unityunity