Help with raycasting

Trying to make my boat only work on water terrain, but it always prints “Not on water”, even when the boat is on land and not water.

Script:

local boat = script.Parent
local main = boat.PrimaryPart

local moveVectors = {
	["Left"] = true, 
	["Right"] = true,
	["Front"] = true,
	["Back"] = true,
}

local function checkVectors()
	for i,v in pairs(moveVectors) do
		local ray = Ray.new(main.CFrame.p, (i == "Left" and main.CFrame.rightVector * -10) or (i == "Right" and main.CFrame.rightVector * 10) or (i == "Front" and main.CFrame.lookVector * 10) or main.CFrame.lookVector * -10)
		local hit, hitPos, material = workspace:FindPartOnRayWithIgnoreList(ray, {boat})
		if material == Enum.Material.Water then
			moveVectors[i] = false
		else
			moveVectors[i] = true
			print("Not on water")
		end
		print(hit,hitPos,material)
	end
end

while wait(.5) do
	checkVectors()
end

What does it print for the material? Looking at the dev Wiki for FindPartOnRayWithIgnoreList, the Material is the 4th thing given, not the 3rd

Try changing

local hit, hitPos, material = workspace:FindPartOnRayWithIgnoreList(ray, {boat})

To

local hit, hitPos, normal, material = workspace:FindPartOnRayWithIgnoreList(ray, {boat})

First of all, you are using the deprecated raycasting method (which might not be your problem but still, it would help).
The new workspace:Raycast() function is super powerful and can help you fix your problem.
If you want to use the new workspace:Raycast() functionality, watch my video on the topic linked here

It was just printing 0,0,0 for the material.

I’ll try that now

That’s probably why then, the 3rd thing given from FindPartOnRay is the normal, aka the angle at which what you’re hitting is orientated at. If you make material the 4th thing to get, it should work

Now it’s printing Air, which I find weird since it’s not air, it’s water terrain.

We’re getting close. I’m not sure if this related but I think it’s not working since you’re only checking for water left right forward and backward, there’s no down checks, which it’s probably contributing to it only printing air

I’ve changed my script to this:

local boat = script.Parent
local main = boat.PrimaryPart


local function checkVectors()
	local ray = Ray.new(main.CFrame.p, main.CFrame.LookVector * 10)
	local hit, hitPos, normal, material = workspace:FindPartOnRayWithIgnoreList(ray, {boat})
	if material == Enum.Material.Water then
		print("On water")
	else
		print("Not on water")
	end
	print(hit,hitPos,material)
end

while wait(.5) do
	checkVectors()
end

How would I send the ray down instead of up?

local ray = Ray.new(main.CFrame.p, main.CFrame.UpVector * -10)

Should do the trick

1 Like