I’m making a gun system that use a button to fire a gun I created a cursor to raycast the position what I want to achieve is to get the crosshair position from the ScreenGui by using :Raycast() and not mouse position because most mobile users using their thumbstick while using a gun the touch position would get messed up
local screenPosition = fakeCursor.AbsolutePosition + (fakeCursor.AbsoluteSize / 2)
local screenSize = mainGui.AbsoluteSize
local imagePlaneDepth = screenSize.Y / (2 * math.tan(math.rad(camera.FieldOfView) / 2))
local direction = Vector3.new(screenPosition.X - (screenSize.X / 2), (screenSize.Y / 2) - screenPosition.Y, -imagePlaneDepth)
local raycastResult = workspace:Raycast(camera.CFrame.Position, (camera.CFrame:VectorToWorldSpace(direction)).Unit * 999, raycastParams)
if raycastResult then
local char = raycastResult.Instance:FindFirstAncestorOfClass("Model") or raycastResult.Instance.Parent:FindFirstAncestorOfClass("Model")
if char and char:IsDescendantOf(game) then
local humanLink = char:FindFirstChild("HumanoidLink")
if humanLink and humanLink:IsA("ObjectValue") and humanLink.Value and humanLink.Value:IsDescendantOf(game) then
local plr = Players:GetPlayerFromCharacter(humanLink.Value.Parent)
if plr then
fakeCursor.BackgroundColor3 = if checkTeamKill(player, plr)
then Color3.fromRGB(85, 255, 0)
else Color3.fromRGB(255, 255, 255)
end
else
local plr = Players:GetPlayerFromCharacter(char)
if plr then
fakeCursor.BackgroundColor3 = if checkTeamKill(player, plr)
then Color3.fromRGB(85, 255, 0)
else Color3.fromRGB(255, 255, 255)
end
end
else
fakeCursor.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
end
end
Hey there, I think what you are specifically looking for is the Camera:ViewportPointToRay() method. It raycasts from a position on the screen. It’s exactly what is needed for an FPS game.
You should use ViewportPointToRay, it’s only inaccurate if you haven’t enabled IgnoreGuiInset on the ScreenGui, and if it isn’t enabled, your crosshair isn’t even centered on the screen.
It’s because I use AbsolutePosition from the cursor frame
local currentPositionOnScreen = fakeCursor.AbsolutePosition
local inputRay = camera:ScreenPointToRay(currentPositionOnScreen.X, currentPositionOnScreen.Y)
local endPosition = inputRay.Origin + inputRay.Direction
local cameraPosition = camera.CFrame.Position
local raycastResult = workspace:Raycast(cameraPosition, (endPosition - cameraPosition).Unit * 5000, raycastParams)
local plr = nil
if raycastResult then
local char = raycastResult.Instance:FindFirstAncestorOfClass("Model") or raycastResult.Instance.Parent:FindFirstAncestorOfClass("Model")
if char and char:IsDescendantOf(game) then
plr = Players:GetPlayerFromCharacter(char)
local humanLink = char:FindFirstChild("HumanoidLink")
if humanLink and humanLink:IsA("ObjectValue") and humanLink.Value and humanLink.Value:IsDescendantOf(game) then
plr = Players:GetPlayerFromCharacter(humanLink.Value.Parent)
end
end
end
fakeCursor.BackgroundColor3 = if plr and checkTeamKill(player, plr)
then Color3.fromRGB(85, 255, 0)
else Color3.fromRGB(255, 255, 255)
What do you mean by “it can only raycast the top of the cursor”? I think it may be caused by you using AbsolutePosition without setting the crosshair’s AnchorPoint to 0.5, 0.5, and if you have set it to that, then can you explain or show a video or image of how ViewportPointToRay is not working?
Also,
Should be
local endPosition = inputRay.Origin + (inputRay.Direction * 5000)