Raycast has strange collisions

I made a raycast so that I can make a wall hopping mechanic in my game, but I’m having an issue where the raycast for some reason just collides with anything and everything.

There are no error’s, here’s the script:

local char = game.Players.LocalPlayer.Character or game.Players.LocalPlayer.CharacterAdded:Wait()
local humanoid = char:WaitForChild("Humanoid")
local root = char.PrimaryPart

local origion = root.CFrame.Position
local direction = root.CFrame.Position + Vector3.new(1, 1, 4)

local vizual = Instance.new("Part", workspace)
vizual.Anchored = true
vizual.Position = origion
vizual.CanCollide = false
vizual.Name = "Visualizer"

local params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Blacklist
params.IgnoreWater = true
params.FilterDescendantsInstances = {char, vizual}

game:GetService("RunService").RenderStepped:Connect(function()
	origion = root.Position
	vizual.Size = Vector3.new(1, 1, 4)
	vizual.CFrame = root.CFrame * CFrame.new(0, 0, -2)
	
	local forwardRay = workspace:Raycast(origion, direction, params) if forwardRay then
		print(forwardRay.Instance)
	end
end)

Shouldn’t it be
local root = char:WaitForChild("HumanoidRootPart")

This doesn’t make a difference.

The PrimaryPart of Character Models are automatically be set to the HumanoidRootPart , so it doesn’t really make a difference

Something that has been bugging me for a long time I think finally clicked inside my head, and what you’re actually doing here is adding more to the Raycast’s predicted Position

Think of it like this:

image

We have 4 Squares that are all colored differently: Blue, Green, Yellow, and Red that each have a same X & Z Position of 0, but each Y Position is different

What we want to do here, is check to make sure that Green Block sends a Raycast so that it hits the Red Square

Now of course we’d have to go ahead and include a Blacklist, since our Yellow Square will get into the way of our Raycasting but now, what if we were to try out your situation on our example here?

local RayParams = RaycastParams.new()
RayParams.FilterType = Enum.RaycastFilterType.Blacklist
RayParams.FilterDescendantsInstances = {workspace.YellowSquare}

local Origin = workspace.GreenSquare.Position
local Direction = Origin + Vector3.new(0, -40, 0)

local Raycast = workspace:Raycast(Origin, Direction, RayParams)
print(Raycast.Instance)

Now here’s something interesting, of course our Raycast works fine, but the .Instance is actually different as it prints back the BlueSquare and not our RedSquare that we should’ve expected:

image

This is because we’re adding the Origin variable to our Direction, cause Raycasting adds both the Origin, and Direction Vectors together so in reality, we get this instead as our actual Ray Position:

local RayDestination = Origin + Direction

Which is why you may see CFrame.LookVector as a direction in some cases, cause we want to Raycast what’s facing that specific way

Now let’s say that we remove our additional Origin in our Direction variable, and only reference where we want it to go:

local RayParams = RaycastParams.new()
RayParams.FilterType = Enum.RaycastFilterType.Blacklist
RayParams.FilterDescendantsInstances = {workspace.YellowSquare}

local Origin = workspace.GreenSquare.Position
local Direction =  Vector3.new(0, -40, 0)

local Raycast = workspace:Raycast(Origin, Direction, RayParams)
print(Raycast.Instance)

Now if we run this just fine, then hey! It works!

image

The Direction parameter of a Raycast is basically adding onto the Origin’s Vector3, which then gets your Raycast Result

The direction on where you want to exactly Raycast though is dependent for your situation

If you want to Raycast facing forward, then you can just simply use something like local direction = root.CFrame.LookVector * 4

I’m also just noticing this now, but you’re saving the direction variable, and not changing it every frame where you should cause otherwise, that direction Position will save & will keep constantly firing Raycasts at that exact same spot no matter what, so add the local direction within your loop:

local humanoid = char:WaitForChild("Humanoid")
local root = char.PrimaryPart

local origion = root.CFrame.Position

local vizual = Instance.new("Part", workspace)
vizual.Anchored = true
vizual.Position = origion
vizual.CanCollide = false
vizual.Name = "Visualizer"

local params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Blacklist
params.IgnoreWater = true
params.FilterDescendantsInstances = {char, vizual}

game:GetService("RunService").RenderStepped:Connect(function()
	origion = root.Position
    local direction = (root.CFrame.LookVector * 4) + Vector3.new(1, 1, 0) 

	vizual.Size = Vector3.new(1, 1, 4)
	vizual.CFrame = root.CFrame * CFrame.new(0, 0, -2)
	
	local forwardRay = workspace:Raycast(origion, direction, params) if forwardRay then
		print(forwardRay.Instance)
	end
end)

I do hope though that this gives you a better understanding on how Raycasting fully works, cause it definitely took me a while :sweat_smile:

2 Likes