alt text Many games have managed to do this and I understand the logic a bit, but I can't seem to implement it. I basically want to create a field (a trigger in this case) that acts as a body of water. The player object collides with this trigger and starts "swimming on it's surface".

I then want to make it to where when the player presses a particular key, they dive under the water and are able to swim around freely in it until they reach the surface.

The best examples I can say is the swimming system in Zelda games and the swim system in Mario Galaxy games. I believe that as far as logic, the water should constantly lift the player to the water's surface. I also may want to ignore gravity while in the water. Lastly, I need to allow him to move in any direction while underwater. I'm thinking that I will have the joystick control the rotation/direction he is swimming while UNDER the water and have another key work as acceleration.

Here is the code I managed to produce. This is currently attached to the Waterbox trigger object.

 function OnTriggerEnter (hit : Collider) 
    {
     if (hit.transform.tag == "Player") 
       { 
        var controller : ThirdPersonController = hit.GetComponent(ThirdPersonController);
        Debug.Log("enter");
        hit.gameObject.GetComponent(ThirdPersonController).inWater = true; 
        //controller.animation.Play("swim");

        }
    }

    function OnTriggerStay(hit : Collider)
    {
    var controller : ThirdPersonController = hit.GetComponent(ThirdPersonController);
        if(controller.inWater)
                {
//Swimming mechanic logic goes here?
                    controller.gravity = -controller.defaultGravity/10; //Default Gravity = 20.0
                }
    }

    function OnTriggerExit (hit : Collider) 
    { 
        var controller : ThirdPersonController= hit.GetComponent(ThirdPersonController); 
        if (controller.IsGrounded !=null) 
        hit.gameObject.GetComponent(ThirdPersonController).inWater = false; 
        //controller.animation.Stop("swim"); 
        controller.gravity = controller.defaultGravity;
        Debug.Log("Left the water"); 
    } 

As far as moving around in the water freely, I'm not really sure how to do that. I believe something like flight mechanics could mimic this?

water-surface trigger and a water-body trigger, with the body trigger overlapping the surface trigger,

Then putting a script on the player to check for any collisions with the water-surface and the water-body

=======Surface======== + =====water body==== ---->player y axis locked =======Water body===== ---->player y axis free

You can then check for a key press to indicate the player wants to dive or leave that out to float or swim according to the triggers the player is in

Basically broken down it could be:

If the trigger for the water body touches the player enter swim mode

if the trigger for the water surface touches the player and swim mode is active enter breast stroke mode

if none of those are true continue as normal walking the earth

----------------------------

for the swim and walk modes with different keys you could use a script or you could use a prefab of the player swimming , if you wanted to use a script just go :

rigidBody.gravity =false //This is not the correct spelling

or make his weight very low

I don't know how you determined you're controls so I cant help you there , how about just adding something to you're script that checks if he's walking or swimming or doing anything else then call the correct script accordingly you could separate them and use [requirecomponent(components name here)]

Hope I helped and hope I didn't say too much bool=false

Give the swimmerObject component rigidbody, MouseOrbit and constantForce (from Standart Assets). MainCamera should be attached to the swimmer as a child.

First, consider swimming on the water surface. Not use gravity (rigidbody.useGravity = false).

void FixedUpdate()
{
  //move follow       
  if (Input.GetButton("Fire1"))
  {
     currentSpeed += Time.deltaTime;
  }
  else
  {
    if (currentSpeed > 0)
        currentSpeed -= Time.deltaTime;
  }
  constantForce.relativeForce = new Vector3(0, 0, currentSpeed);

  //turn right/left
  rigidbody.AddRelativeTorque(0, Input.GetAxis("Horizontal") * 5, 0);
}

Set rigidbody.useGravity = true and use Rigidbody.AddTorque with ForceMode.Impulse for diving from the shore. http://unity3d.com/support/documentation/ScriptReference/Rigidbody.AddTorque.html Gravity must be disabled in water.

For swim to the water surface when the diver has dived, it is necessary to configure the script MouseLook like for FPS. The mouse turns must rotate the swemmerObject. Use only Rigidbody.rotation for it and only into FixedUpdate(); http://unity3d.com/support/documentation/ScriptReference/Rigidbody-rotation.html

Use CapsuleCollider for swimmerObject and MeshCollider for pool walls. Don't use transforms for moves.

As a trigger the water surfase you can use separate MeshCollider like isTrigger or check the value of the axisY into the Update();

How about something using the variable isSwimming , and having that set to true if you step into the water area, that will play the animation, and can look like you are swimming. Then, since isSwimming is only true if you are in the water area, you could have it so when isSwimming is true, translate the character downwards, and after 3 seconds, push him back up, then you would just have to instantiate the gui coloring when you enter the area. Perhaps the isSwimming variable could do this too.

For anybody finding this thread and looking how to set up swim mechanics 2022. (dive thing is not in this video)

Create two classes (two scripts) for Player Object,
the first one is normal movement
the second one for swimming…

alternate them with OnTriggerEnter and OnTriggerExit