I’m trying to make a custom swimming system but I’m running into some issues when it comes to detecting if a player is in water. As a heads up, I do not believe I can use the default swimming states because they don’t seem to be usable without the default swimming mechanics (I’ve tried countering their effects but it just didn’t work well.) https://streamable.com/br4qfa
I’m currently shooting a ray from my old position to my new one, seeing if there is water in the way, and if there is I start swimming. I then do this process backwards to detect if a player has left water (ray shoots from new position to old position to try to find water). The problem occurs when the water is next to another type of terrain-- I’ve tried using smart rays that try again if they run into the wrong type of material, thus ignoring the previous material, but it seems like if two different types of terrain are right next to eachother, the ray doesn’t work.
I.e only the surface of the cobblestone is present, not the surface of the water.
I’ve tried using region3 and reading from voxels but as far as I can tell this is just simply too imprecise. You randomly start swimming when you’re besides water, and randomly stop swimming while in water. Unless I am doing it wrong.
You can do something where the height changes based on “region”, I don’t know if what I’m suggesting is a more complex solution than what someone else may suggest, but you can have it so that if a player is in a certain area, the height of the water changes based on how it’s painted on.
Seems needlessly complicated. I know some games who do this for small things, but something like having zones specifically blotted out for every single place in the game is like adding an extra layer to map design that really shouldn’t need to exist.
Oops, I thought what you were looking for is custom swimming animation. A little misunderstanding. However, you can set up an event to detect when an animation plays to enable that system?
I.e the default state changes that the default animation script relies on are completely disabled outright to stop the default roblox swim physics from kicking in.
(Besides there’s no need to read an animation to tell what a player is doing-- the animation script already provides the code that finds if you’re swimming, which again, is by using states)
If I did I don’t remember what the solution was anymore. Probably something janky like teleporting an invisible part over the player every frame and checking if this part’s velocity started increasing on the Y axis from buoyancy
I have this piece of code that checks if the players camera is underwater, and then applies an affect to it. You could probably easily adapt it to checking for the humanoid root part. @Kizylle
local function _underwaterCheck() : nil
local offset : number = 0.01
local cameraPosition : Vector3
local camera : Camera = workspace.CurrentCamera
local region : Region3?
task.spawn(function()
while task.wait(0.2) do
cameraPosition = camera.CFrame.Position
region = Region3.new(Vector3.new(cameraPosition.X - offset, cameraPosition.Y - offset, cameraPosition.Z - offset), Vector3.new(cameraPosition.X + offset, cameraPosition.Y + offset, cameraPosition.Z + offset)):ExpandToGrid(4)
if region then
local material = workspace.Terrain:ReadVoxels(region, 4)
if material[1][1][1] == Enum.Material.Water then
--YOUR CAMERA IS UNDER WATER
print("underwater")
else
--YOUR CAMERA IS NOT UNDER WATER
print("on land")
end
end
end
end)
end