- Home /
Allowing player to swim or dive in water?
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?
Answer by DragonReeper · Nov 06, 2010 at 01:11 PM
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
I used the Third Person Platformer example as my base, so the control scheme is the same from it. I know how to transition from walk to water via script, but the logic/code I'm having problems with. The same for the water surface issue. $$anonymous$$y character is using a CharacterController, not a rigidbody and verticalSpeed is what is used to deter$$anonymous$$e gravity in a sense.
Wait a sec I'm gonna see if I can hack the third person script.
I deducted the following from my experiments add a script to the water let that trigger the players swim$$anonymous$$g with a coordinate of the top position of the water, I think you could then use that to "fake" the swim$$anonymous$$g then just check if the player is in the allocated Y axis and put him in float mode , else continue as a underwater aqua man
As an extra suggestion I suggest you starting catching your null values in safe code and that you set your characters controller in saved states such as "Walking" - "Swim$$anonymous$$g" etc.
Answer by Robotron18 · Nov 09, 2010 at 06:24 AM
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();
The character object itself uses a charcterContoller and a modifed version of ther thirdpersoncontroller script. Will I have to swap object once he hits the water with an object that is constructed the way you specifed?
I think swap object are needed in any case. I've been sea game also and passed the stage of complete solutions. $$anonymous$$arine game requires non-standard solutions. For example, you can drown a swimmer when he stopped to swim without a problem. I do not know what you all come to $$anonymous$$d during the development of the game.
Answer by LawyerOfGod · Feb 25, 2015 at 07:21 PM
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
I have used two scripts and works very fine for me... this should not be a great problem.!
Answer by THENATHE · Dec 28, 2012 at 05:24 AM
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.
Answer by jtagamesinfo · Jan 31 at 05:38 PM
https://www.youtube.com/watch?v=K8lOEmdZ78o
For anybody finding this thread and looking how to set up swim mechanics 2022. (dive thing is not in this video)