Raycasts failing inconsistently, unsure of my source of error

My raycasts are failing and I don’t know why. I know they’re failing because RaycastResult is consistently nil, though it seems like I have the correct parameters here. I’m almost certain that the problem is the way I get the direction vector, but I can’t tell - it’s my first time using the new raycast method and despite it being clear that there’s no difference in the logic between these and the deprecated methods, it does seem different.

I cannot share all of production code but I can share the raycasting I’m doing. Below is test code that can be ran in StarterPlayerScripts. You will see that it will only work sometimes (when on the move or pointed at a certain angle), but at other times it refuses to cast at all despite being in an appropriate location. I need to have those casts all work.

local Players = game:GetService("Players")
local RunService = game:GetService("RunService")

local LocalPlayer = Players.LocalPlayer
local PlayerMouse = LocalPlayer:GetMouse()

local MouseRaycastParams = RaycastParams.new()

local character
local humanoidRootPart

--- Cast a ray every frame
local function heartbeat()
    local mouseHitPosition = PlayerMouse.Hit.Position

    local mouseCastResults = workspace:Raycast(
        humanoidRootPart.Position,
        (mouseHitPosition - humanoidRootPart.Position),
        MouseRaycastParams
    )

    print("CastResults:", mouseCastResults)

    --- Create a ray visualiser
    do
        if not mouseCastResults then
            print("Could not cast")
            return
        end
        local distance = (mouseCastResults.Position - humanoidRootPart.Position).Magnitude
        local line = Instance.new("Part")
        line.BrickColor = BrickColor.new("Hot pink")
        line.CastShadow = false
        line.Material = Enum.Material.Neon
        line.Transparency = 0.75
        line.Name = "RayVisual"
        line.Anchored = true
        line.CanCollide = false
        line.Size = Vector3.new(0.1, 0.1, distance)
        line.CFrame = CFrame.new(mouseCastResults.Position, humanoidRootPart.Position) * CFrame.new(0, 0, -distance/2)
        line.Parent = workspace
    end
end

--- Handle character variables
local function characterAdded(newCharacter)
    character = newCharacter
    humanoidRootPart = newCharacter:WaitForChild("HumanoidRootPart")

    MouseRaycastParams.FilterDescendantsInstances = {newCharacter}
end

LocalPlayer.CharacterAdded:Connect(characterAdded)
RunService.Heartbeat:Connect(heartbeat)

if LocalPlayer.Character then
    characterAdded(LocalPlayer.Character)
end

Looking for substantiated, knowledgeable answers, not speculation. Thank you in advance.

3 Likes

Sometimes you need to make the ray a little longer, try changing

(mouseHitPosition - humanoidRootPart.Position)

to

(mouseHitPosition - humanoidRootPart.Position)*1.1

If that doesn’t work please give us the output!

1 Like

are you talking about this?

because if i change (mouseHitPosition - humanoidRootPart.Position) to say (mouseHitPosition - humanoidRootPart.Position).Unit*300 to get a direction, it works consistently and it doesn’t fail to detect anything

2 Likes

Forgot about multiplying the unit vector, I’ll see if it works. Do you perhaps know why the raycasts fail when I do not extend it though? I was under the impression that I wouldn’t need to set the length myself this way to get a proper direction vector, since the calculation for the direction of a vector is target - origin.

Not sure if it’s a bug, but sometimes if you set the ray length to the exact distance between points, it just doesn’t connect. You gotta add a lil extra

1 Like

I would’ve preferred if I didn’t have to set the length myself and I could catch arbitrary distances, but I guess this’ll work too. Just for the future’s sake. The current casts I need to do only need to work across short distances so managing distance myself’d work.

Weird error. I’ll look at your slight multiplication when I need arbitrary distances in the future. Thank you for the suggestion. Extending the unit vector seems to guarantee consistency.

What do you need the raycast result for anyways? Could you just use mouse.Target?

I prefer not to. Using Target like that seems archaic and a click would be able to go through a wall, which I don’t want. On top of checking distance I’d have to cast a ray which could potentially end up going far. A simple ray across a short distance packs that work all into one.