Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

water floating

Discussion in 'Scripting' started by Zu01, Jan 26, 2011.

  1. Zu01

    Zu01

    Joined:
    Aug 17, 2010
    Posts:
    95
    Ive created a simple water animation and shade. I got it to work. But how exactly would I make it so you float in the water? So far I use -9.81 as my gravity. Is there anyway to enable and disable a constant force or temporairaly change gravity?
     
  2. elveatles

    elveatles

    Joined:
    May 2, 2009
    Posts:
    147
    Is the water at a constant level or are there waves? Do you have a screenshot of what this looks like right now? As far as I know, the Physics engine doesn't have anything for floating. You have the option of writing the physics code yourself, or maybe you could attach an invisible spring joint to fake it. Don't know how good that would look though. You'd also have to program the spring joint to follow your object unless it went below a certain point.
     
  3. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,434
    There was a recent thread on "buoyancy" that included a couple scripts that would do what you want. It used rigidbodies and forces to simulate an object floating.
     
  4. Zu01

    Zu01

    Joined:
    Aug 17, 2010
    Posts:
    95
    Elveatles - The water is flat. The problem is the only movement I am good at is things like transform.position.something +/- = something.

    Bigkahunab - Where may I find these scripts, do the cost money?
     
  5. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,434
    Search for "buoyancy". Alexzzzz posted a couple scripts (free) in a thread a week or so ago. There's also a buoyancy script for sale in the asset store that looks pretty nice also.
     
  6. Zu01

    Zu01

    Joined:
    Aug 17, 2010
    Posts:
    95
    It's not neccacairy for buoyancy that I need. I want to be able to move around, like flying but in water. You know, you can swim up and down in water. That's the princaple.
     
  7. .Samuel.

    .Samuel.

    Joined:
    Jan 20, 2011
    Posts:
    11
    If you only want to swim around then you could use rigidbody.addForce in combination with Input.GetAxis. And you could use rigidbody.velocity.FORWARD to point it to the direction you are swimming. And then you only have to check if you are inside the water with a raycast or something.
     
  8. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
    I want to answer this is a theoretical and practical way.... Since boats and such are one of the things I want to control in my simulation later. I thought I would play with the idea without using any previous package.

    Concept:
    Create 4 "floats" which the boat floats on. Positioned front, left, back and right. Apply force at the float points equal to the depth of the float * the -gravity * mass / 4... this will give a floating item some type of buoyancy. Next, the boat must have a hull, so I use a mesh collider.

    Later on, apply force at an engine point for power and left and right force at the rudder point. (but those don't matter for now)

    I found that I needed to add rigid bodies to my floats, and I had to connect them using joints. They have no collision, so they never strike anything.

    Application:
    The script has to be inclusive. It must be applied to the base game object and the collision must be applied to it from that object. The collision object must be a mesh but is not necessarily to be attached to the base object. (It should be imported from your 3d modeling program, so it should all be connected)

    The script will manage creating all the elements nessicary to make the object function with no extra creation steps from the user. (as 99% of all my scripts are. What can I say, I am lazy)

    Code:
    Code (csharp):
    1.  
    2. var collisionObject : Transform;
    3. var waterLine : float;// adjust the waterline of the boat on the y axis
    4.  
    5. var mass=1000;
    6. var centerOfMass=Vector3(0,0,-0.2);
    7.  
    8. var text:GUIText;
    9.  
    10.  
    11. private var floats=Array();
    12. private var doScript=false;
    13.  
    14. function Start(){
    15.    
    16.     if(!collisionObject)
    17.         return;
    18.     //create the collisionHull
    19.     try{DestroyImmediate(collisionObject.collider);}catch(e){};
    20.     var MC=collisionObject.gameObject.AddComponent(MeshCollider);
    21.     MC.sharedMesh=collisionObject.gameObject.GetComponent(MeshFilter).mesh;
    22.     MC.smoothSphereCollisions=true;
    23.     MC.convex=true;
    24.     collisionObject.renderer.enabled=false;
    25.     var mat : PhysicMaterial=new PhysicMaterial();
    26.     mat.dynamicFriction=0.2;
    27.     mat.staticFriction=0.1;
    28.     mat.bounciness=0.2;
    29.     collisionObject.collider.sharedMaterial = mat;
    30.     var size=MC.sharedMesh.bounds.size;
    31.    
    32.     //create rigidbody
    33.     var rb=transform.gameObject.AddComponent(Rigidbody);
    34.    
    35.     //front float
    36.     floats.Add(NewFloat("Float-Front", Vector3(0,waterLine,size.z)));
    37.     floats.Add(NewFloat("Float-Left", Vector3(-size.x,waterLine,0)));
    38.     floats.Add(NewFloat("Float-Right", Vector3(size.x,waterLine,0)));
    39.     floats.Add(NewFloat("Float-Back", Vector3(0,waterLine,-size.z)));
    40.    
    41.    
    42.     resetCenterOfMass();
    43.     doScript=true;
    44. }
    45.  
    46. function resetCenterOfMass(){
    47.     rigidbody.mass=mass;
    48.     rigidbody.drag=1.0;//things are harder to move in the water.. ;)
    49.     rigidbody.angularDrag=mass * 0.005;// the bigger it is.. the less it will turn in water (not accurate, but acceptible)
    50.     rigidbody.centerOfMass+=centerOfMass;
    51. }
    52.  
    53. // create a basic rigidbody
    54. // returns a transform
    55. function NewFloat(name, position){
    56.     var retval=GameObject().transform;
    57.     retval.parent=transform;
    58.     retval.localPosition=position;
    59.     retval.name=name;
    60.     var rb=retval.gameObject.AddComponent(Rigidbody);
    61.     var fj=retval.gameObject.AddComponent(FixedJoint);// rigid body of the float is attached using a joint
    62.     fj.connectedBody=transform.rigidbody;
    63.     return retval;
    64. }
    65.  
    66. function Update () {
    67.     if(!doScript)
    68.         return;
    69.        
    70.     // this is arbitrary, if you wanted, just get the bound top of a box
    71.     // for animated vertex water, get the raycast down hit of this point. That will produce the bob
    72.     var waterLevel=8.0;
    73.    
    74.     var s="";
    75.     for(i=0; i<4; i++){
    76.         var y=mass/4 * (waterLevel-floats[i].position.y) * (-Physics.gravity.y);
    77.         if(y<0.0)y=0.0;
    78.         s+=y + " : "+ floats[i].name +"\n";
    79.         floats[i].rigidbody.AddForce(Vector3.up * y);
    80.     }
    81.     if(text)text.text=s;
    82. }
    83.  

    Conclusion:
    I found that the object floated, bobed and did most everything it was supposed to. It had a "lean" where the Center of mass was not the true center of the object, but it this were a real boat it would have a heavier engine and not be noticeable.

    Since this was applied to a vehicle controller test application. The object (which really was a road barrier) floated, moved when hit, did not have excessive movement or excessive roll.

    I think in the end, I would want to add modifiers for sinking my boats, and some under water physics.