FindPartOnRay only detecting at a short distance

I am making a gun that will detect if a bullet has hit a player. However, when setting up the ray with length of 20, and printing the object hit while directing the gun at a dummy, it continuously prints nil until the Firer (the part with initial position of bullet when in the gun) is about 0.5 studs away from the dummy.

Script:

-- Take Firer to be a part on the gun with a position that a bullet will start firing from.
while true do
    local FTRay = Ray.new(Firer.CFrame.Position, Firer.CFrame.Position + (Firer.CFrame.UpVector * 20))
    local intPart, intPosition = workspace:FindPartOnRay(FTRay, character, false, true)
    print(intPart)
--Additional Test to visualise ray and see if it actually intersects through the object
-- This test shows the end position of the ray by creating a part
	local Test = Instance.new("Part")
	Test.Name = "RayReach"
	Test.Size = Vector3.new(1,1,1)
	Test.Position = Firer.CFrame.Position + (Firer.CFrame.UpVector * 20)
	Test.Parent = game.Workspace
	Test.Anchored = true
	Test.CanCollide = false
--
    wait(0.5)
end

When I adjusted the length of ray from 20 to 500 (replace above * 20 with * 500), the detection was slightly better and the ray could now detect the object from about a range of 15 studs. What is this discrepancy? Shouldn’t a ray detect parts within its length? Why do I need to adjust the length of ray significantly for the detection to work and only for such a small distance?

Thanks.

Try removing the parentheses so you’re multiplying the unit instead of upvector.

It still doesn’t work. I actually thought that adding the parenthesis previously would solve the problem but the problem is still there with or without parenthesis.

1 Like

Oh wait, I forgot pemdas for a second, (Firer.CFrame.Position + Firer.CFrame.UpVector) * 20

Did some research and found out it is a param

Yep, according to Roblox’s Developer Hub Tutorial on How to Make a Laser Gun, including this parameter is to ignore the player’s character when shooting the gun.

1 Like

Here is the script in action with ray of length 20 studs. Notice that FindPartOnRay only registers for almost negligible distance away. (I’ve changed Firer to my character’s HumanoidRootPart)

What’s the intended direction of the ray? The direction vector that you supplied to Ray.new() looks a little weird. If the direction supposed to be the direction that the front of the player’s torso is facing, then you should just do this:

Ray.new(Firer.CFrame.Position, Firer.CFrame.LookVector * 20)

Since the LookVector(or UpVector, or RightVector) is a directional unit vector, you should be able to simply take the vector as-is, multiply it by the distance, and put it in the Ray.new function.

1 Like

Yep, I had changed it up just now to make it simpler. Now, instead of using a LookVector I do:

Ray.new(Firer.CFrame.Position, (Firer.CFrame * CFrame.new(0,1000,0)).Position)

The problem is still there though, although I am starting to think that it is just the nature of how the ray is built into Roblox. So instead of setting the ray to just a length of 20, I set it to 1000 and now, it can detect parts up to about 20 studs, good enough for me. If there is a solution, I am still open to it though.

The second parameter of the ray is a direction vector, not a final position. In the paintball tutorial, you can get the direction towards your mouse with this snippet of code

local ray = Ray.new(tool.Handle.CFrame.p, (mouse.Hit.p - tool.Handle.CFrame.p).unit * 300)

As you can see, by subtracting the position of the mouse.Hit and the origin of the ray, you get a vector specifying the direction. You can get the unit vector by calling .unit, which returns a vector with magnitude 1. Getting the unit vector is important because, through scalar multiplication (multiplying by 300 in this case), you can get a vector with the exact magnitude you specify.

I think with your previous examples, you just got lucky and a ray given the POSITION you defined happened to be pointed in a way that intersected with the dummy.

I think you are right. The previous code on LookVector was rather weird. Using the test part as above

I would sometimes get the part in front of my gun and at other times when I rearrange the code slightly, the test part spawns at a different position, a little to the right of the dummy which made the ray intersect the dummy to reach the part which prompted me to changed from LookVector to

So I agree with you, I definitely got lucky.
What I am still not sure, however, is why is LookVector * 20 not a direction vector? It is a unit vector that is scaled by 20, which would point in that direction, right?

If you are referring to Aesthetical’s solution, Firer.CFrame.LookVector * 20 is a direction vector constructed the way you wanted. However, you replied to him saying that you used

(Firer.CFrame * CFrame.new(0,1000,0)).Position

instead of the lookvector.

In your sample, you used the UpVector and not the LookVector