Getting the players mouse from the server

Plain and simple, yet no clue why this won’t work:

Client

local mouse = player:GetMouse()

local tool = script.Parent

local event = tool:WaitForChild('Event')

event:FireServer(mouse)

Server

event.OnServerEvent:Connect(function(player, mouseEvent)
	print(player, mouseEvent)
	mouse = mouseEvent
end)

Print Output: NinjoOnline, nil

When I print mouse in the client script however it prints Instance, so it’s obviously there. Unless Instances can’t be passed through from Client to Server? Any help or ideas please?

5 Likes

The server cannot see the Mouse. Ever. Therefore it is nil.

Remember, passing instances through remotes is simply passing a reference to that instance. If the other side doesnt have access to that instance, the reference is nil.

Its like passing a reference of a server script through a remote to the client.

1 Like

Like all forms of input, the player’s Mouse exists only on their client. It cannot be passed to the server for this reason.

Instead of passing the mouse itself to the server, why not pass whichever property that the server needs to it? For example, if the server needs the mouse’s hit position, simply pass that directly:

event:FireServer(mouse.Hit)

If you need the server to request specific properties of the mouse, you can use RemoteFunctions.

24 Likes

You can send Mouse.Hit and Mouse.Target


You guys @Fm_Trick , @Dandystan beat me to it.

1 Like

I agree. For anyone who’s interested, this post describes an alternative to using Mouse.Hit, and can easily be adapted to Mouse.Target (optionally with a target filter) if you have a little knowledge of ray casting:

4 Likes

It’s good to note that invoking clients from the server using RemoteFunctions should be done with caution and a time limit, as an exploiter can put an infinite delay on the invocations.

local InvokeClient = function(remote, player, ...) -- returns: response time (or nil if failed), tuple client returned values
    local response, values
    spawn(function()
        local start = tick()
        values = {remote:InvokeClient(player, ...)}
        response = tick() - start
    end)

    local seconds = 0
    while not response do
        if seconds >= 10 or not player.Parent then -- the player might have left the server
            break
        end
        wait(0.1)
        seconds = seconds + 0.1
    end

    if not response then
        warn("Failed to get a response from " .. player.Name .. " through RemoteFunction: " .. remote.Name)
    end

    return response, values and unpack(values)
end

I haven’t made a script like this before so any improvements are welcome.

6 Likes