Issue with pointing raycast towards the camera from the barrel of a gun

Hey developers,

I’ve been having some trouble with raycasting from the barrel of a gun in the direction of the camera in a way that it ends up aligning with the crosshair.

So far i have been able to get it (kinda) working, the only issue is that it uses a raycast from the camera, and if that raycast is nil it doesn’t quite line up with the gun.

This is the code to get the direction the raycast needs to go in:

function getShootDir()
	local cameraHit = workspace:Raycast(camera.CFrame.Position, camera.CFrame.LookVector.Unit * 1000, params)
		
	local shootDir
		
	if cameraHit then
		warn("camera raycast hit")
		shootDir = cameraHit.Position
	else
		warn("camera raycast didn't hit")
		shootDir = camera.CFrame.Position + (camera.CFrame.LookVector * 1000) -- i think this line is the issue
	end
	
	return (shootDir - gunModel.PrimaryPart.Position).Unit, gunModel.PrimaryPart.Position
end

Heres an example of what i mean:

when cameraHit hits something:

when cameraHit is nil and the other code has to emulate it hitting something:

feel free to try it for yourself to get a better idea of what i mean in this test place:

as the comment said in the code i provided above, i think this line is likely the culprit:

shootDir = camera.CFrame.Position + (camera.CFrame.LookVector * 1000)

If you have any questions please feel free to ask.

Thanks in advance for any help i get!

-snake_case

Have you tried using Mouse.Hit?

yes i have, and it works fine using mouse.Hit. The only reason i can’t use it is to maintain mobile and console support, so i have to use alternatives.

1 Like

The FE gun kit uses it, and it works on mobile. Would it not still work?

Also:

on PC the mouse is locked to the center of the screen, so i could use mouse.Hit to get the 3D position of the center of the screen (which is where the crosshair always is), but on mobile, since there is no cursor, it would go to where the button to shoot the gun is. So that cameraHit variable is supposed to get the 3D position of the center of the screen, but if the raycast is nil, then the broken line of code runs instead.

Ah, gotcha. Maybe try adding an offset CFrame and messing with the values a bit?

1 Like

After messing with the offset a bit i’ve found it doesn’t really fix the issue. I think another issue here is i don’t really know how raycast directions work, or why subtracting the position of the gun from cameraHit does something.

Can you show us a gif or screenshot with the LookVector offset by 100 rather than 1000? maybe 1000 is just so far away that after 700 studs or so, the laser is 1 pixel thin or less from your perspective, and so appears to end short

1 Like

When i multiply it by 100 instead of 1000 the laser goes past the crosshair. (you might have to zoom in to see it if the embedded image is too small)

Desktop Screenshot 2022.12.04 - 16.42.45.97

1st.
You do not need to use .Unit on CFrame.LookVector, as it’s a unit vector to begin with.

2nd.
1000 studs is a far distance, that, even in the second picture where the shot hits the wall, most likely points to the same direction cameraHit would have hit if it was true.

Anyways, shootDir would be the same no matter the outcome, with the difference being the length of your new vector.

3rd

Vector subtraction is usually used to get a vector that points at another vectors head.
Ex

--(TOPointAt - At), then get a unit vector 
local PointAtBVector = (BVector - AVector).Unit
1 Like

how much should i multiply it by to have it be identical to when cameraHit isn’t nil?

instead of multiplying the lookvector by 1000 i’m multiplying it by 250, which helps but this still might be an issue. Since the angle between the gun and the ray would be different depending on the length I’m not really sure if i can effectively solve this problem.