Wrote up a short script to get 3D mouse hit from UserInputService


#1

It’s kind of irritating that the UserInputService doesn’t have a way to give 3D position. MouseMovement > Position returns the pixel-based screen coordinates (as a Vector3: [X, Y, 0]).

The script, which runs locally, uses that 2D coordinate to get the mouse’s position via the Camera’s ScreenPointToRay method. If you have something else that works feel free to post it.

local Players = game:GetService("Players")
local Camera = workspace.CurrentCamera
function GetMousePoint(X, Y)
	local RayMag1 = Camera:ScreenPointToRay(X, Y) --Hence the var name, the magnitude of this is 1.
	local NewRay = Ray.new(RayMag1.Origin, RayMag1.Direction * 1000)
	local Target, Position = workspace:FindPartOnRay(NewRay, Players.LocalPlayer.Character)
	return Position
end

--Listen to UserInputService's "InputChanged" event, and get the 
--Position property of the InputObject, which will be a Vector3. Pass X and Y into the
--function. It will return a position in the 3D world.

Finding a part a Player clicked?
Featured Games Program - Getting Started & Expectations
#2

Have you tried using PlayerMouse instead for this?
http://wiki.roblox.com/index.php?title=API:Class/PlayerMouse

Just set TargetFilter to the player’s character and simply read its properties. This is already kept track of anyway so might as well be used.

i.e.:

local mouse = game.Players.LocalPlayer:GetMouse()

-- either this or listen to PropertyChanged on "Character" whenever that's out:
game.Players.LocalPlayer.CharacterAdded:connect(
   function(char)
      mouse.TargetFilter = char
   end
)

-- read mouse.Hit, mouse.Target whenever you want

The only thing it doesn’t have a property for is the surface normal at the hit position, but it didn’t seem like you needed that. If you do need that you can raycast with mouse.UnitRay (ray already constructed for you)

EDIT: actually mouse.Hit returns a CFrame that has the hit normal as one of its axis vectors, I think.


#3

I believe it doesn’t work so well with touch screens (mobile & tablet), especially if you want to drag things in 3D space. I used a similar method to Xan for my work on it.


#4

My only complaint with this method is that target filter doesn’t accept a table of things, only one instance


#5

Mouse.Hit returns a CFrame whose lookVector is in the direction from Camera.CFrame.p -> Mouse.Hit.p – of course its Point is at the clicked point.

I would have used the Mouse for this normally, but since most new scripts are expected to use the UserInputService, it’d be kind of useless to have a UserInputService listener on top of a mouse listener in the aspect that it feels more redundant to have both.

This is kind of a personal thing, so I would use the mouse if I just need mouse input only, but if I need to use mouse alongside the UserInputService at all I’ll just use my little function.