I am trying to make a small raycast to detect whether or not the player’s camera is in water.
However, it’s not detecting terrain at all and most of the time just outputs nil. Sometimes it detects the player’s head.
This is a local script running under Player Scripts:
while true do
local camera = workspace.CurrentCamera
local raycastParams = RaycastParams.new(
Enum.RaycastFilterType.Whitelist,
{workspace.Terrain},
false
)
local raycastResult = workspace:Raycast(camera.CFrame.Position,camera.CFrame.LookVector*1,raycastParams)
for i=1, 15 do
print(string.rep(" ", i%2))
end
print(raycastResult)
wait()
end
I don’t think the RaycastParams constructor takes any arguments. Try this instead:
local raycastParams = RaycastParams.new()
--//Assign fields directly to the new object
raycastParams.FilterDescendantsInstances = {character} --//Anything else you want the ray to ignore
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
local result = workspace:Raycast(camera.CFrame.Position, camera.CFrame.LookVector, raycastParams)
if result and result.Material == Enum.Material.Water then
print("The ray hit water!")
end
local result = workspace:Raycast(characterModel.Head.Position, camera.CFrame.LookVector)
On second thought though, I don’t think there’s a clear shot to this. I think this has always been a caveat of raycasting where if the origin position is inside of what you’re trying to cast a ray to it doesn’t work properly. The only thing I can think of is exaggerating the origin position so it’s always above the water, then casting a ray long enough downward to still be able to hit the water. The only thing that’d need to change is we’d want to make sure the player is actually swimming or in the water, because otherwise it’ll say they’re in water when they might not truly be.
if result and result.Material == Enum.Material.Water and characterModel.Humanoid:GetState() == Enum.HumanoidStateType.Swimming then
print'blah'
end