What's the best way to detect when the player clicks on another player?

  1. What do you want to achieve?
    A trustable method on how when a player hover overs another player and clicks, it returns the player that was clicked.

  2. What is the issue?
    I cannot find a useful method.
    I know about raycast, But this is basically 2D to 3D

  3. What solutions have you tried so far?
    I tried looking on the DevHub, but I couldn’t find anything.

1 Like

If you know about raycasting then did you try it? Was there anything wrong with it? Because normally that would be an easy way to do it if you just raycast from camera position to mouse.Hit.Position

Since a mouse is 2D, you can’t do a origin. Unless I’ve missed something, I don’t think Raycast.Origin accepts Vector2.

mouse has a Hit property that describes the mouse hit in 3d position

1 Like

That’s my point. How do I get where the mouse (a 2D object) clicked in Vector3?

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

print(mouse.Hit.Position) --a position in 3d space somewhere in the map

Since the Mouse is obselete, the best way to do this would be to retrieve the mouse location with UserInputService, and then use Camera:ScreenPointToRay to convert the 2D position into a Ray. You can then raycast with the given origin and direction.

Since I get a Vector3 Position, How can I get what instance was clicked?
Edit: I need to read.
Give me a sec.

It seems Raycast returns nil, Why?
Code:

local mouse = game.Players.LocalPlayer:GetMouse()
local UserInputService = game:GetService("UserInputService")
local Camera = workspace.CurrentCamera

mouse.Button1Up:Connect(function()
	print(1)
	local screenpoint = Camera:ScreenPointToRay(mouse.X, mouse.Y, 1)
	local RayParams = RaycastParams.new()
	RayParams.FilterDescendantsInstances = {}
	RayParams.FilterType = Enum.RaycastFilterType.Blacklist
	local Raycast = workspace:Raycast(screenpoint.Origin, screenpoint.Direction, RayParams)
	print(Raycast.Instance)
end)

No raycasts needed, just a little use of Mouse.Target

local Player = game.Players.LocalPlayer
local Mouse = Player:GetMouse()

Mouse.Button1Down:Connect(function()
	if not Mouse.Target then return end
	local Part = Mouse.Target
	local Character
	if Part:FindFirstAncestorWhichIsA("Model") then Character = Part:FindFirstAncestorWhichIsA("Model") end
	if Character and game.Players:GetPlayerFromCharacter(Character) then
		local PlayerTargeted = game.Players:GetPlayerFromCharacter(Character)
		print(PlayerTargeted)
	end
end)


You can then fire a remote event if you want server sided changes.

3 Likes

mouse has been superseded by UserInputService so here is how you can do it without using mouse

here is a demo project
ClickOnCharacter.rbxl (34.8 KB)

and this is the code in the project

local userInputService = game:GetService("UserInputService")

userInputService.InputBegan:Connect(function(input, processed)
	if processed == true then return end
	if input.UserInputType ~= Enum.UserInputType.MouseButton1 and input.UserInputType ~= Enum.UserInputType.Touch then return end
	local mouseLocation = userInputService:GetMouseLocation()
	local ray = workspace.CurrentCamera:ViewportPointToRay(mouseLocation.X, mouseLocation.Y)
	local result = workspace:Raycast(ray.Origin, ray.Direction * 1000)
	if result == nil then return end
	local model = result.Instance:FindFirstAncestorOfClass("Model")
	if model == nil then return end
	local player = game.Players:GetPlayerFromCharacter(model)
	if player == nil then return end
	print("Clicked on:", player.Name)
end)
1 Like

ScreenPointToRay returns a unit ray(magnitude is set to 1), you need to multiply the direction by a certain amount.
Example:

local Raycast = workspace:Raycast(screenpoint.Origin, screenpoint.Direction * 5000, RayParams)
local Game = game
local Players = Game:GetService("Players")
local Player = Players.LocalPlayer
local Mouse = Player:GetMouse()

local function OnButton1Down()
	local Part = Mouse.Target
	if not Part  then return end
	local Model = Part:FindFirstAncestorOfClass("Model")
	if not Model then return end
	local Player = Players:GetPlayerFromCharacter(Model)
	if not Player then return end
	print(Player.Name)
end

Mouse.Button1Down:Connect(OnButton1Down)
1 Like