Issue with my water detection

So I have a custom swimming system in my game since I dont like the default roblox swimming. This swimming system REQUIRES that I know the top Y position of the water and the bottom Y position of the water so I can move u up and down when u swim but obviously wont let you swim above the waters surface because then you’d just be flying.

What I do is I raycast in a loop twice. One raycast is 500 studs above the player and casts 500 studs down the other is 500 studs below the player and raycasts up. If both raycasts detect water and the players Y position is below the surface of the water and above the bottom point of the water I declare them in water. The issue with this system however is that if I have something like this:

Lets say I have a cave
image
Above is a pool of water and below is also a pool of water. Clearly you can see the issue here is that it will consider me within the bounds of water if I try to jump over that water just because there is water above me. How could I fix this?

I’d suggest just reworking the system.
In my opinion it’d be better to have zones where you’re considered “in water”.
You can achieve that with invisible parts for the zones and spatial queries for example.

I think it would be a much more easy to work with system
In the image below the red box is the water hitbox, it would be an invisible and uncollidable part slightly lower than the water level (so that you can’t walk/float on the water using the swimming system)


Instead of the raycast just use spatial queries to detect if the player is in the invisible part.

3 Likes

I guess my question is why the heck are you using 500 studs as your measurement?
Why not just 1 stud dimensions to see if the raycast hits water? If it does then the player is in the water.

2 Likes

raycasts wont work if its inside the water itself (ignores the water, this behavior is the same with parts). I used a large number like 500 because I may have large bodies of water in my game that could go super deep. So I start really high and really low just to prevent starting the raycast inside the water.

1 Like

I was thinking of doing this as well but seems annoying to have to put invisible parts everytime I want to create water just to support my swimming system. I will probably do this as a last resort if I cant find any better solutions.

1 Like

Another solution potentially would be to have a way to detect when a player is in terrain water without raycasts (which I am unaware on how to do). And then if they are inside water we find the top and bottom by raycasting in increments of five. E.g I’ll raycast from 5 studs up in the air to find the surface and if I dont find the surface then I’ll increase it by 5 again and repeat that until the surface is found. Could also make it 10 stud increments since I doubt I’d have 2 bodies of water 10 studs above or below another.

Well right now you also have to manually write out all the coordinates to make sure you’re in water (unless you do it differently, but I don’t know how else you would check if the player is in water with your current system without X, and Z position checks + the Y raycast). I’d find that more annoying to be honest.

Also I misunderstood a bit, I thought you abandoned the default Roblox water altogether (for stylistic reasons for example) which would make my solution less annoying

1 Like

I dont use the X and Z coordinates at all. I just check if the player is within the Y coordinates of the water.

Is there a way to tell if a player is inside of terrain water? If there is then I can do my previous mentioned solution of incremental raycasts to avoid the problem.

I may be forced to just do the incremental raycasting without another way to detect if a player is in water. I wanted to detect if they are in the water before doing all the raycasts just to be better on performance but oh well.

Could you run something on the client that detects if the player is in the part every frame by using workspace:GetPartsInParts()?

1 Like

I am using terrain water so I cant use getpartsinpart.

You can take the bounds of your character, and see what percentage is in the bounds of water. If it’s less than 50, no swimming. You can use terrain water, and overlay an invisible collision part.

1 Like

The issue is how do we even get the bounds and detect water?

Region3 | Documentation - Roblox Creator Hub This may do

1 Like

Region3 is deprecated according to staff but I literally cannot find any other ways to detect if ur inside water which is kinda frustrating. Idk why they’d deprecate it if its the only way to detect terrain water.

If you only check the Y coordinate then you won’t be able to have any sorf of elevation in your game, are you sure that’s okay?
For example a hill with water inside of it is impossible:

or just a ramp going down will also be impossible:

You will also have to make sure that no terrain goes too low or too high because then you might get falsely flagged as in water.

Sounds like much more of a headache to me rather than just adding a big part to each lake/water

Is there a way to tell if a player is inside of terrain water?

I couldn’t find anything on it but there could be.
Apparently workspace.Terrain.Touched only fires when you touch water but that seems like a very inconsistent solution

1 Like

I don’t see how a hill with water doesnt work. Also it doesnt just check terrain it makes sure its actually water.

The blue dot is a player and the red lines are the raycasts.
image
Its not just raycasting once it raycasts in a constant loop and updates the Y position just for that issue. If I used parts I’d have to use ramps or rotated parts just to detect that ramp on the side.

Edit: to clarify terrain cant block the raycast either. I have a custom function that will raycast beyond any terrain obstructing the water. Not that my game uses any terrain anyways the only terrain used in my game is water.

Couldnt you just use Roblox’ swim, but only as in the HumanoidState? That way you could read the state, and if it’s swim then you’re in water.

1 Like

I have to disable this state for my own custom swimming so no I cant use it to detect if a player is in water unfortunately.

You can do a voxel scan at the player’s position. That’ll return occupancy.

1 Like