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)
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
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