I needed a way for players to swim inside of parts, but 1-1 with roblox’s smooth terrain voxel water swimming for ease of use/familiarity
Instead of any custom swimming controller trickery, I made a rather simple module that tricks the humanoid into thinking it’s in voxel water + some simple emulated drag and buoyancy to make it sufficiently close to the real thing
There’s no setup required or external dependencies, control scheme is the exact same so no need to worry about cross platform support or anything
local plr = game.Players.LocalPlayer
local char = plr.Character or plr.CharacterAdded:Wait()
local hum = char:WaitForChild("Humanoid")
local hrp = char:WaitForChild("HumanoidRootPart")
local Antigrav = Instance.new("BodyForce")
Antigrav.Force = Vector3.new(0,workspace.Gravity * hrp:GetMass(),0)
local Enabled = false
game:GetService("RunService").Stepped:Connect(function()
if hum.MoveDirection.magnitude == 0 then
hrp.Velocity = Vector3.new(0,0,0)
end
if Enabled == true then hum:ChangeState(Enum.HumanoidStateType.Swimming) end
end)
local UIS = game:GetService("UserInputService")
UIS.InputBegan:Connect(function(input)
if input.KeyCode == Enum.KeyCode.G then
for _,z in pairs(char:GetDescendants()) do
if z:IsA("BasePart") and z ~= hrp then
z.Massless = true
end
end
if Enabled == true then
Enabled = false
Antigrav.Parent = nil
for _,z in pairs(Enum.HumanoidStateType:GetEnumItems()) do
if z.Name ~= "Swimming" then
hum:SetStateEnabled(z,true)
end
end
else
Enabled = true
Antigrav.Parent = hrp
for _,z in pairs(Enum.HumanoidStateType:GetEnumItems()) do
if z.Name ~= "Swimming" then
hum:SetStateEnabled(z,false)
end
end
end
end
end)
Pretty nice! However it’s kinda weird (as in animations) if i have R6 enabled. (not sure if its the fault of head movement scripts that i have in my game)
Noticed a bug, if you jump in water while swimming in R6 mode, the character suddenly floats to the bottom and behaves like if it was in low gravity enviroment.
This is a simple and easy-to-use module, though it does have some bugs that I’d appreciate be checked out
Buoyancy does not remain the same when gravity is changed – I checked the module to see if you were recalculating every time gravity changed. I found that it did in fact recalculate, so there’s likely to be a miscalculation in one of the forces
Heavy characters (like big characters) cannot swim downwards as the buoyancy force counteracts the swimming force. I cannot confirm if the behavior is the same with R15 though
Cool resource, using it in a game, but one small bug and hopefully you can help with this, the module doesnt work with mobile as it disables jumping while swimming, which hides the mobile button, is there a way to give this back?
If you can please contact me here or on Discord, user is the same as my Roblox user.
self._stateMaid:Add(game:GetService("UserInputService").JumpRequest:Connect(function()
self._didJump = true
end))
-- Add this after that line ^
local TouchGui = Players.LocalPlayer.PlayerGui:FindFirstChild("TouchGui")
local button = TouchGui and TouchGui:FindFirstChild("JumpButton",true)
if button then
button.Visible = true
end