How to detect a swimming part?

Hello. I’m currently updating my swimming system in my game. However, it has become harder than I thought.

I understand how to handle the positioning of the character, but I can’t figure out how how to detect if the player is in water. Something similar to what I’m making is this:

https://gyazo.com/1815bab60a7fb8c6815d904adc169cdc

The character is able to swim in any body of water in game, and many of them are at different Y positions. As long as they are called ‘water’ in workspace.

How should I go about detecting if a character is in a water body?

I’ve tried using .Touched, but the problem is that the bodies of water are non-collideable.

maybe use magnitude?
30char30char

Maybe by using :Touched() ??

I have also tried to use magnitude, but that doesn’t work.
This is inside a renderstepped loop.

local waterPart = searchForWater(20)
if not swimPart and waterPart then
	swimPart = waterPart
	print("found part")
end

and this is the function. It never prints “no targets.”

function searchForWater(mag)
	if swimPart then
		return
	end
	
	local targets = {}
	local waterPart
	
	for a, b in pairs(workspace:GetDescendants()) do
		if b:IsA("BasePart") and waterList[b.Name] and b.Transparency ~= 1 then
			targets[#targets + 1] = b
		end
	end
	
	if #targets == 0 then
		print("no targets")
		return waterPart
	end

	for i = 2, #targets do
		local closest = targets[1]
		local closestDistance = (closest.Position - root.Position).magnitude
			
		for i = 2, #targets do
			local target = targets[i]
			local distance = (target.Position - root.Position).magnitude
			
			if distance < closestDistance then
				closest = target
				closestDistance = distance
			end
		end
		
		if (closest.Position - root.Position).magnitude <= mag then
			waterPart = closest
		end
	end
	
return waterPart
end

I said in the original post that I’ve already tried it, but apparently you can’t use .Touched for non-collideable objects.

Okay then what about :GetTouchingParts()

They may be using a Region3 and checking if the player is within that Region3 before making them swim.

:GetTouchingParts() can’t be use for non-collide objects, unless there is TouchInterest (AKA: Something is connected to its Touched event). Look at this post for more information [Obsolete] Simple trick to make GetTouchingParts work with non-CanCollide parts

3 Likes

I automatically assumed that one would add it.

1 Like

How would I use a Region3 for this situation?

This is a pretty good tutorial I found (yes it’s from 2018, but it’s still valid.)
You could replace the while true do loop he made with a RunService.Stepped or .Heartbeat loop if you want it to run a little faster, or without making your code stop at that point.