Raycast isn't Returning Anything

local origin, direction = char.Head.Position, ((char.Head.Position + (char.Head.CFrame.LookVector * 30)) - Vector3.new(0,10,0))
local params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Whitelist
params.FilterDescendantsInstances = {workspace.Terrain}
params.IgnoreWater = false
local ray = nil
local part = Instance.new("Part",workspace)
part.Position = direction
part.Anchored = true
repeat 
	wait()
	ray = workspace:Raycast(origin,direction,params)
until ray ~= nil
local hit = ray.Instance
print(hit.Material)

No matter how much it repeats, the raycast doesn’t return anything. It’s like it’s ignoring everything.

This is intentional, see Raycast. Raycast returns nil if it doesn’t hit anything.

You might want to consider debugging your points. Since the result of Raycast can be nil it might not be helpful to construct a line visualising the raycast so create two parts instead representing the origin and direction then drop them into the Workspace. Your raycast should be between said points. Check where they exist when Raycast returns nil. If there’s no parts between the two points then you may want to reconfigure your direction a little more.

For the sake of reference, what’s your use case? What are you intending to do specifically?

I need to check if there is water infront of the character. And I HAVE visualized the points. There is terrain between them.
And yes. I know it’s intentional. However, it shouldn’t be returning nil because it DOES hit terrain. :pensive:

Here are the two points. There IS in fact water between them and ignore water is turned off.

Is it because a part is already touching the water?

I used a beam to visualize the ray and it is most certainly touching terrain.

Right, my bad! I did do a bit more diving into this issue and recalled some forgotten knowledge.

Alright, so I did try creating my own raycast code to check this problem out. One change I did make was using the HumanoidRootPart instead since that’s canonically a lot more stable if you need to run some kind of position-bound game logic rather than something visual.

With relatively the same math applied as you, one of the results I got was that the raycast would always occur if the terrain cells were in the front left corner of my character. This in mind it helps me to narrow down the potential cause and that would be the calculation involved for direction.


With only the first parts of the calculation.

Since direction is often confused as an endpoint instead of a relative vector, I had a go by only using Vector3.new(0, 10, 0) which appropriately casted 10 studs down relative to my HumanoidRootPart. This means that the direction calculations can use some changes based on that.

In truth having paid attention I probably could’ve seen the issue a while back. Knowing that the direction is already relative to your origin, you don’t need to specify it again! Just take out the head.Position part from your directional calculation and that should resolve it.

If you need a point of reference and a test file, here’s what I used:
TerrainDetectRepro.rbxl (27.9 KB)

Have a walk around and see which material gets printed to your console. Check Camera in the Workspace for the visualisers, you may need to size them up to see more clearly what they’re hitting. Example below when I sized them up to (2, 2, 2).

tl;dr:

Direction is already relative to origin, so get rid of the head.Position bit of your direction math. Just extend the LookVector out 30 and then subtract 10 from the Y axis to lower the detection point.

(head.CFrame.LookVector * 30) - Vector3.new(0, 10, 0)

Thanks so much! I’ll try this out right away!

O. It ignores terrain for some reason. It prints out ‘Plastic’ which I assume is my basepart material. Unless terrain is all plastic.

Nvm. I fixed it. All thanks to you! Tysm!

Just as a point of reference for anyone else as well:

Terrain itself doesn’t have a material. Thankfully the Material of the hit object is one of the members of the RaycastResult so you can access the current material without needing to read the voxels or anything (arguably a little painful).

This thread works with the old raycast functions but is still applicable. Posting just in case anyone else sees this thread and is wondering how to resolve the Terrain material issue when using similar code.