Allow players to swim but not go underwater?

I want to allow players to swim around in water, but I don’t want them to go underwater. Is this possible? How could I do this?

For context, I’m making an FPS, and I want players to be able to swim around, but it would break the gameplay if they could dive down into the water.

7 Likes

Either have barriers, or change the gravity. There are more complex ways, those are the simplest in your case. Does your FPS use custom avatars, and or the classic FPS games method, where you make arms and duplicate them to the player’s camera?

3 Likes

If you know exactly how far your water goes down, you could simply prevent them from going down by checking their depth and applying a small up force.

Something I learned was I could put a region around the character’s head to check if they were submerged in water… which would take from their oxygen and essentially drown them. I think this is a fine case for determining if the player is in water. It can be somewhat expensive though. But knowing you… Haha you should be able to optimize it in no time.

7 Likes

Very simply you can place an invisible block immediately below the minimum depth needed for an avatar to swim.

2 Likes

An invisible false floor part could still allow players to be fully underwater if you make the floor low enough to guarantee even the tallest avatars won’t be glitching in and out of running state.

My first thought would be a BodyPosition on the root part, which normally has MaxForce (0,0,0) and Position (0, seaLevel, 0), but when a player’s humanoid is in Swimming state, MaxForce becomes non-zero on the Y axis if the root part Y position is below seaLevel. The seaLevel in this case would be a Y level of the surface of the water, or some small offset from it that you tune for appearance. You’d probably want a small dead zone so that characters can get out of the water smoothly.

3 Likes

If you set the Massless property on all parts in a character to true then they won’t be able to go under, and will float to the top.

This could easily be done by over-riding the StarterCharacter, or by using a script when the player’s character spawns.

3 Likes

Assuming the player could jump while in the water, they would end up getting a super jump if their character was massless.

2 Likes

This could have the same problems as using custom density to make them very buoyant, in that the character can bob too high and glitch between falling and swimming states at the surface of the water.

2 Likes

No, there is no “super jump” effect as result of massless.

2 Likes

Yeah, I did further testing and I realize now that this is possible.

2 Likes

Thanks everyone! Here are my findings so far:

  • Humanoid.StateChanged is terrible and hardly works.
  • Humaonid.Swimming works, but you have to listen to all the other state events in order to detect when the swimming stops. I decided to go with this.

Adding a static part underneath the water would work, but it prevents players from diving underneath when they jump in from a high altitude.

My solution thus far is to create a local part that is generated underneath the player while they are swimming. This video demonstrates it:

12 Likes

I know this is over a week old, but I’ve found another solution and just want to toss my 2 cents in.

At it’s current stage, it’s not the best solution; that being said it’s definitely going in the right direction I believe.

local RunService = game:GetService("RunService")
local player = game.Players.LocalPlayer
repeat wait() until player.Character
local character = player.Character

character.Humanoid.Swimming:Connect(function(speed)
	local descendants = character:GetDescendants()
	if(speed > 2) then
		for index, descendant in pairs(descendants) do
			if(descendant.Name ~= "HumanoidRootPart" and descendant:IsA("Part")) then
				descendant.Massless = true
			end
		end
	else
		for index, descendant in pairs(descendants) do
			if(descendant.Name ~= "HumanoidRootPart" and descendant:IsA("Part")) then
				descendant.Massless = false
			end
		end
	end
end)

Granted the user can rotate his character, this does not allow him to dive below the water (and continue diving).

Here’s a GIF:

As you can see, you can point your character down but it won’t allow you to go below the water.
I’m sure there’s a way to prevent this if you were to give it some thought, I’ll be thinking about it.

3 Likes

How come this function is “terrible”?

Just curious

1 Like

See relevant thread here:

It’s an issue for the whole state system.