Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

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

Asked by
ZeroBits 142
8 years ago

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.

0
set the math.huge to 1000, because that is the max ray distance for roblox. faster that way :p TheDeadlyPanther 2460 — 8y
0
Thanks for the tip! ZeroBits 142 — 8y
0
lol, seems like I've run into problems. ZeroBits 142 — 8y
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) XAXA 1569 — 8y
0
Oh. So Depth is distance from camera? They really should specify this stuff on the wiki. Thanks for the help! ZeroBits 142 — 8y

1 answer

Log in to vote
-1
Answered by 8 years ago

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.

0
The OP did not use Mouse.Target. Also, the OP explicitly stated that they will not use the Mouse object at all. XAXA 1569 — 8y
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. Zedreadr 10 — 8y
0
I'm not using mouse at all because I wanted to make something without using mouse. That's really my only reason. ZeroBits 142 — 8y
Ad

Answer this question