Water part's jumping behavior not working correctly

  1. What do you want to achieve?
    A working water part, imo parts are way easier to work with than terrain.

  2. What is the issue?
    If the character jumps while in the water they get stuck in this animation not able to move up or down until they leave the water.

  3. What solutions have you tried so far?
    I tried looking on the DevForum, and although I found answers to other issues, I didn’t find any for this one specifically.

Here’s the script that handles all swimming related stuff:

function CheckIfPlayerIsInArea(Part, Character)
	local touching = Character.HumanoidRootPart:GetTouchingParts()
	
	for i, v in pairs(touching) do
		if v == Part then
			return true
		end
	end
	
	return false
end

game.Workspace.Water.Touched:Connect(function() end) -- If we don't do this, the CheckIfPlayerIsInArea function won't work properly

function leftWater()
	print("Left water")
	
	game.Players.LocalPlayer.Character.HumanoidRootPart.SwimVelocity:Destroy()
	game.Players.LocalPlayer.Character.Humanoid:SetStateEnabled("GettingUp", true)
end

function enteredWater()
	print("Entered water")
	
	local bv = Instance.new("BodyVelocity")
	bv.Name = "SwimVelocity"
	bv.Parent = game.Players.LocalPlayer.Character.HumanoidRootPart
	
	game.Players.LocalPlayer.Character.Humanoid:SetStateEnabled("GettingUp", false)
	game.Players.LocalPlayer.Character.Humanoid:ChangeState("Swimming")
end

local inWater = false

game:GetService("RunService").Heartbeat:Connect(function()
	if game.Players.LocalPlayer.Character then
		if game.Players.LocalPlayer.Character:FindFirstChild("HumanoidRootPart") then
			if CheckIfPlayerIsInArea(game.Workspace.Water, game.Players.LocalPlayer.Character) then
				if not inWater then
					inWater = true
					enteredWater()
				end
				
				game.Players.LocalPlayer.Character.HumanoidRootPart.SwimVelocity.Velocity =
					game.Players.LocalPlayer.Character.Humanoid.MoveDirection *
					game.Players.LocalPlayer.Character.Humanoid.WalkSpeed
			else
				if inWater then
					inWater = false
					leftWater()
				end
			end
		end
	end
end)

Here’s the place file:
aceolotls assets.rbxl (38.6 KB)

1 Like

One small solution I’ve found is that you can run a while loop to constantly update the players state as such:

function enteredWater()
	print("Entered water")
	
	local bv = Instance.new("BodyVelocity")
	bv.Name = "SwimVelocity"
	bv.Parent = game.Players.LocalPlayer.Character.HumanoidRootPart
	
	game.Players.LocalPlayer.Character.Humanoid:SetStateEnabled("GettingUp", false)
	
	while inWater == true do
		wait(.1)
		game.Players.LocalPlayer.Character.Humanoid:SetStateEnabled("FallingDown", false)
		game.Players.LocalPlayer.Character.Humanoid:ChangeState("Swimming")
		
		if inWater == false  then
			break
		end
	end
end

This causes a weird issue with the “SwimVelocity” not being found if you leave the water though, and sometimes you still get the falling animation depending on how long you set the wait() time to, if it’s left blank then you don’t get it as far as I’ve seen.

One thing to note is to place the “inWater” variable before the “enteredWater()” function.

A simple fix for the “SwimVelocity” not being found upon leaving the water is placing an if statement to check if it’s there or not:

if game.Players.LocalPlayer.Character.HumanoidRootPart:FindFirstChild("SwimVelocity") then
					game.Players.LocalPlayer.Character.HumanoidRootPart.SwimVelocity.Velocity =
						game.Players.LocalPlayer.Character.Humanoid.MoveDirection *
						game.Players.LocalPlayer.Character.Humanoid.WalkSpeed
				end
1 Like

Not the solution I’m looking for, but perhaps game.Players.LocalPlayer.Character.Humanoid:SetStateEnabled("FallingDown", false) could be useful.

1 Like

Unfortunately, neither your idea nor mine worked :confused:

Constantly changing the Humanoid state to Swimming make the player look like they were hiccupping, and my idea made them swim to the surface even when letting go

Disabling the Jumping state fixed the falling animation issue, but that’s a problem too as normally you’d swim to the surface faster while holding the jump button.

It isn’t the way I hoped it had hoped it to work, but here’s a temporary solution:

for i, inst in pairs(game.Workspace:GetDescendants()) do
	if inst.Name == "Water" then
		game.Workspace.Terrain:FillBlock(inst.CFrame, inst.Size, Enum.Material.Water)
		inst:Destroy()
	end
end