Hi, Would someone willing to help me through this? I searched google, youtube, demo etc. and there aren't much to show from it.

I'd like to base my swimming/diving like Mario64, learning things such as

1) Switch to swim control mode 2) Floating on water ( no need to based on shader, just faking floating up and down) 3) A button to propel forward (swim and underwater) 4) Slowly sinking down or floating up depends on where you at under water 5) Underwater effect under the surface

My player control with camera orbit and basic moving code like:

if Input.is_action_pressed("move_forward"):
	direction -= transform.basis.z

I'm sorry if this asking too much but I couldn't find anything to start off whatsoever.

Thank you

Steps I use to help clarify my mind: (basically game design things)

define the type of game, style of game, theme of game, what device will it be played on, who is target audience

Summarize the game and give notes what about will be fun.

sketch out the various scenes of your game.

write out what you want to happen in each scene and how each scene relates to each other

identify what you want to trigger what actions and how to perform those triggers and actions.

Then I would do a flow chart of each action.

Keeping this document handy gives mission scope and breaks down goals and ideas into action.

Having this document helps you can find tutorials on every step where you struggle because you have diagrammed out what you want to do on each step and then it clarifies your needs.

I found the more time I do on my game design the easier my implementation and getting answers.

BTW Have you made an FPS yet in godot? you may find many of your questions are aspects common to FPS shooter games.

Hi Thank you for response. Yes I have done FPS and few other player control (CodeWithTom, Garbaj, GDQuest..)

But I'm not at the level to make game right now. I asked because there is nothing to guide me through coding to do a character swim or fly, which I think is kinda fundamental for player controls

I've seen a lot of answers such as "it's easy just make it like flying" or "try make a press that push swim forward" or "let's do 2d but 3d is the same" That doesn't help me at all. (If you were to look at my past threads you'd understand what it takes to help me lol)

Also some demos are too advanced to be usable for specific thing (There is one Mario64 demo made from here long ago) when all I want to learn is how to add swim to this basic character

This question is vague now but I know I'll be asking stuffs I listed so I thought is better to put all in one thread so ppl get the overall picture, I don't know. (unless it is preferable start new thread on each point then that's fine too)

I've done a few of these questions for a couple projects, so I might be able to help a bit

1) Switch to swim control mode

This one depends a bit on level design and how you want water to function. The simplest way is to have a water plane that is at a certain height and if the player goes below this height, water mode is activated. This is a very cheap and easy way to know when a player is underwater (and needs swim controls) or whether they are above the surface. Likewise, you can tell if the player is on the surface by seeing if it's within a close range from this Y position.

However, that method is also a tad limiting in terms of level design, as you have to make sure all your non-water areas are above the Y position and you cannot have pools of water elsewhere. The other way I've done it is to have an Area node and the on_body_entered and on_body_exited (I think that's what they are called) signals to inform the bodies that they have entered/exited a water area. Something like this, for example:

func _ready():
	connect("on_body_entered", self, "on_body_entered")
	connect("on_body_exited", self, "on_body_exited")

func on_body_entered(body):
	if "is_in_water" in body:
		body.is_in_water = true
func on_body_exited(body):
	if "is_in_water" in body:
		body.is_in_water = false

The downside of this method is you cannot really have overlapping water areas, but compared to the other method (Y-plane), it's much more flexible.

2) Floating on water ( no need to based on shader, just faking floating up and down)

The way I did this was to invert gravity so the player floats up when they are underwater. I didn't program anything for floating on the surface of the water, however I did get some floating like behavior as the gravity switched from being inverted to normal as the player broke the surface of the water.

If you want to have just general floating, without necessarily moving the player all the way to the surface, what I can see doing that might work is simply switching the gravity direction from DOWN to UP on a timer when the player is underwater, so they float a little up and then float a little down.

3) A button to propel forward (swim and underwater)

This should be similar to normal movement, I think. I haven't really done this beyond swimming on the surface, in which case I just used my normal ground-based movement code and it worked fine.

4) Slowly sinking down or floating up depends on where you at under water

Not totally sure on this one, but I think it's similar to number 2.

5) Underwater effect under the surface

What I did for my game was attach a RigidBody to the Camera node for the sole purpose of detecting if it's underwater (similar to answer 1) and if it was, I changed the visibility of a TextureRect that had a simple shader that applied slight distortion and color tinting to the screen so it appeared the player was underwater. There's probably better ways to handle it, but it worked decently for my use (though the player wasn't really intended to be underwater for more than a few seconds in that game so... yeah)


Hopefully this helps a bit! This is just how I approached these questions when I was making something similar, but there are many, many different ways to handle this type of thing. :smile:

Thank you for your guidance, at least I know which way should be heading.

Maybe I should make this my little project like jbskks(?) suggest and ask bits of code problem later instead. Maybe move this thread to Project section? then I will update as I figure them out

As for 5) Underwater effect, I found same answer with simple instructions overhere. It is quite "hidden" when you're not on twitter or a game developer I guess :#

Finding the right tutorials and codes is HARD. You have to guess how other people phrase what you need and try again and again and again when that doesnt work.

Seriously I spend hours looking for examples to learn from. So you are not alone. :)

Gotta keep grinding :s

1) Switch to swim control mode

I've found the code similar to what's twigleg suggest. I tried to apply it to my player but there is a problem: I could not made my player switch to swim state.

var state = SWIM
var onwater = false
enum {
	MOVE,
	SWIM
}
	
func _physics_process(delta):
	match state:
		MOVE:
			move_state(delta)
		SWIM:
			swim_state(delta)
	
func move_state(delta):
	if onwater == true:
		state = SWIM
		print("onwater")
	else:
		var direction = Vector3.ZERO

		if Input.is_action_pressed("left"):
			direction.x += 1
		if Input.is_action_pressed("right"):
			direction.x -= 1
		
		velocity.x = direction.x * speed
		if direction != Vector3.ZERO:
			direction = direction.normalized()
			$Pivot.look_at(translation + direction, Vector3.UP)
		if onwater == true:
			state = SWIM
			print("onwater")
		velocity = move_and_slide(velocity, Vector3.UP)
		

func swim_state(delta):
	if onwater == false:
		state = MOVE
	else:
		var direction = Vector3.ZERO
		if Input.is_action_pressed("left"):
			direction.x += 1
		print("onwater")


func _on_Area_body_entered(body):
	var onwater = true
	print("truewater")

func _on_Area_body_exited(body):
	var onwater = false
	print("falsewater")

On_body Signals are working But there is no "onwater" from either move or swim_state . Does anyone know what's wrong with my code?

@Gowydot said: Thank you for your guidance, at least I know which way should be heading.

Maybe I should make this my little project like jbskks(?) suggest and ask bits of code problem later instead. Maybe move this thread to Project section? then I will update as I figure them out

If you want that would work! I think you should go with whatever solution you think will work best for you. I generally try to break problems down into smaller bits and work on them one at a time simply because I find it easier, but that's just what works for me. :smile:

As for 5) Underwater effect, I found same answer with simple instructions overhere. It is quite "hidden" when you're not on twitter or a game developer I guess :#

Awesome! Even being semi-active on Twitter and other game development communities (mostly just looking rather than participating though), I find I miss all sorts of cool stuff.

On_body Signals are working But there is no "onwater" from either move or swim_state . Does anyone know what's wrong with my code?

In the signal functions, remove the var before onWater. With the var added, it's defining a local variable with the same name, which shadows (blocks) the global variable with the same name when used. Removing the var should make it work, I think.

oh no..look at where I got this code from link

I know I don't have coding in me but this is just beyond that :s

Thank you

Hi , I'm now at Floating on water

I got the player to float up and down but I face problems with the code

var time = 0
var state = MOVE
var onwater = false
enum {
	MOVE,
	SWIM
}
	
func _physics_process(delta):
	match state:
		MOVE:
			move_state(delta)
		SWIM:
			swim_state(delta)
	
func move_state(delta):
	if onwater == true:
		state = SWIM
	else:
		var direction = Vector3.ZERO

		#Movement Codes Here		
	
		velocity.x = direction.x * speed
		velocity.y -= fall_acceleration * delta
		
		if onwater == true:
			state = SWIM
		velocity = move_and_slide(velocity, Vector3.UP)
		
func swim_state(delta):
	if onwater == false:
		state = MOVE
	else:
		var freq = 1
		var amplitude = 1
		var direction = Vector3.ZERO
		time += delta

		#Movement Codes Here
		
		velocity.x = direction.x * speed
		#Floating code
		velocity.y = sin(time*freq*amplitude)
		
		if onwater == false:
			state = MOVE
		velocity = move_and_slide(velocity, Vector3.UP)

func _on_Area_body_entered(body):
	onwater = true
func _on_Area_body_exited(body):
	onwater = false

? The player is "onwater" at start even though I initiate state to MOVE and onwater to FALSE (Player has not enter the water body)

? Is it possible to make this bobbling code to slowly go upwards as well


velocity.y = sin(time*freq*amplitude)

? The player is "onwater" at start even though I initiate state to MOVE and onwater to FALSE (Player has not enter the water body)

After 3-4 days of trying everything on the code I found out it's the FLOOR collision that was inside the water cube body collision all this time, which triggered my player SWIM state at the start. (Moving the water body up off the floor fixes it) :/

? Is it possible to make this bobbling code to slowly go upwards as well

Probably just gonna make player floating up (velocity.y = gravity * delta) and try to make it bobbling only at the surface somehow

Will move on to 3) with character swimming. Hopefully don't get stuck on something silly again

Sorry about not seeing your earlier reply, I completely missed it! I'm glad you were able to figure out what was causing it not to work though :smile:

Probably just gonna make player floating up (velocity.y = gravity * delta) and try to make it bobbling only at the surface somehow

Yeah, that might be easiest. I haven't tried bobbing underwater in any of my projects, so what I suggested was purely theoretical. I think getting bobbing on the surface should be easier though, since it may happen semi-naturally automatically as the player gets pushed up and down as they transition from touching the surface of the water and pushing past it.

Sorry about not seeing your earlier reply No problem at all and the problem was just silly overlook on my part

Got the Swiming and Floating up/down done

3) Swimming I adapt "AGoodFPSPlayer" dash function for the Mario-like swim (source: aimforbigfoot )

4) Float up/down Placing invisible "underwater" Area node deeper under water. When the Player is under water he will slowly float up to surface but will float down if he's too deep (if hitting "underwater" Area node) . Also add the underwater effects from 5)

The bobbing at the surface is somewhat working..

my noob code: #on _process(delta)

	if $CameraOrbit/Camera.global_transform.origin.y < surface.global_transform.origin.y:
	#just below water surface will float up
		vel.y = gravity * delta
		colorrect.visible = true
	#too deep will float down
		if $CameraOrbit/Camera.global_transform.origin.y < underwater.global_transform.origin.y:
			vel.y = -gravity * delta
	else:
	#or else just bobbing at surface LOL
		vel.y = sin(time*freq)*amplitude
		colorrect.visible = false

I still need to stop player from going above water and maybe adding the jumping into water effect, but I think I got the basics for swiming/diving working as planned =)

Any suggestion for improvment is always welcome

Thank you everyone!

a year later