Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

Is there a simple way to get mouse hit position from its screen coordinates? [ACTUALLY SOLVED]

Keeping this up for future users.

The problem was that the depth argument for ScreenPointToRay is actually where the ray starts, and not the distance of the ray.

Original Post:

I'm switching some of my LocalScripts over to UserInputService, and am trying to remove my reliance on the Mouse object. Is there a method similar to Mouse.Hit, or a simple way to replace it? It doesn't have to use UserInputService exclusively, I just want to shy away from using the Mouse object now that it seems like Roblox is moving more in favor of UserInputService.

Solution:

I discovered a solution shortly after this post, if anyone want to know how I did it, just see below.

So, it turns out, Camera objects have this neat ScreenPointToRay function. It takes three arguments: x, y, and depth. x and y are the screen position. depth is the distance of the ray. It will then return a ray.

I then use FindPartOnRay with the screenpointtoray ray as the first argument, and the player character as the second, and set the third and fourth to false and true respectively. Which returns the target part, the point of intersection, the surface, and the material of the part or terrain. It also ignores the player, and water terrain.

You could also use FindPartOnRayWithIgnoreList if you wanted to have multiple items ignored.

current code:

local fndtn = script.Foundation
local play = game.Players.LocalPlayer
local UIP = game:GetService("UserInputService")
local camera = game.Workspace.CurrentCamera

function getHit(mouseX,mouseY)
	camera = game.Workspace.CurrentCamera
    local ray = camera:ScreenPointToRay(mouseX,mouseY,1000)
	print(ray.Origin)
	local rayorigin = Instance.new("Part")
	rayorigin.Size = Vector3.new(1,1,1)
	rayorigin.Position = ray.Origin
	rayorigin.Anchored = true
	rayorigin.Parent = game.Workspace
	rayorigin.BrickColor = BrickColor.new("Really red")
	rayorigin.Name = "Ray Origin"
	script.OriginGui:Clone().Parent = rayorigin
	print(ray.Direction)
	print(ray.Unit.Direction)
    local target, hit, surface, material = game.Workspace:FindPartOnRay(ray.Unit,play.Character,false,true)
	if target then print(target.Name..":Target") else print("notarget") end
    return hit
end


function inputB(inputObject, gameProcessedEvent)
	if inputObject.UserInputType == Enum.UserInputType.MouseButton1 then
		local X,Y = inputObject.Position.X, inputObject.Position.Y
		local hit = getHit(X,Y)
		clone = fndtn:Clone()
		clone.Position = hit
		clone.Parent = game.Workspace
		height = Y
		wid = X
		placeconnect = UIP.InputEnded:connect(inputE)
		changeconnect = UIP.InputChanged:connect(inputC)
	end
end

function inputE(inputObject, gameProcessedEvent)
	if inputObject.UserInputType == Enum.UserInputType.MouseButton1 then
	placeconnect:disconnect()
	changeconnect:disconnect()
	end
end

function inputC(inputObject, gameProcessedEvent)
	if inputObject.UserInputType == Enum.UserInputType.MouseMovement then
	local X,Y = inputObject.Position.X, inputObject.Position.Y
	if X > (wid) then
		wid = X
		clone.Size = Vector3.new(clone.Size.X+1,clone.Size.Y,clone.Size.Z+1)	
	elseif X < (wid) then
		wid = X
		clone.Size = Vector3.new(clone.Size.X-1,clone.Size.Y,clone.Size.Z-1)
	end
	
	if Y > (height) then
		height = Y
		clone.Size = Vector3.new(clone.Size.X,clone.Size.Y-1,clone.Size.Z)	
	elseif Y < (height) then
		height = Y
		clone.Size = Vector3.new(clone.Size.X,clone.Size.Y+1,clone.Size.Z)	
	end
	end
end

UIP.InputBegan:connect(inputB)

current problems:

The ray's origin seems to be 1,000 studs ahead of the camera. Causing it to ignore everything. image: https://i.gyazo.com/f6ac156f6ed745d1ecefb312e03b2770.png red dots are ray origins.

5 comments

0

set the math.huge to 1000, because that is the max ray distance for roblox. faster that way :p

0

Thanks for the tip!

0

lol, seems like I've run into problems.

0

Where did you expect the origin of the ray would be? Your screenshots seem correct. Have you tried setting depth (the third arg) to 0? (depth is not the length of the ray, but the distance of the ray from the camera)

0

Oh. So Depth is distance from camera? They really should specify this stuff on the wiki. Thanks for the help!

1 answer

okay 1: Why are you using raycasting when mouse.Target does all of that. 2: mouse.Target will return the part that the mouse is pointing to, so using it you can return the part, mouse.TargetSurface will return where the surface the mouse is facing, mouse.Hit will return the CFrame coordinates of where the mouse is pointing to.

I shall send you the code in a PM.

EDIT: I am unable to send you the code because I cannot send you a PM.

3 comments

0

The OP did not use Mouse.Target. Also, the OP explicitly stated that they will not use the Mouse object at all.

0

I don't see why he wouldn't, because it works just fine. You could also use mouse.Ray to get a raycasting of the mouse position to the part that it's facing if you need it. Sometimes you need to modify the OP to get it to work, using raycasting on the mouse uses up WAY too much scripting power.

0

I'm not using mouse at all because I wanted to make something without using mouse. That's really my only reason.

This discussion is preserved as it was. New answers, comments, and votes are closed.