Hello.
I want to make it so i can easily get the player’s mouse position through a server script. (With S-C-S communication)
I have read some documentation but it didn’t help me still.
Thanks.
Hello.
I want to make it so i can easily get the player’s mouse position through a server script. (With S-C-S communication)
I have read some documentation but it didn’t help me still.
Thanks.
You can create a “ping” remote event that the server fires to the specified client and a “response” remote event which the client fires back once it registers the “ping” event. Something like this:
-- Server
local mouse
local targetPlayer = -- A player variable
GetMousePing:FireClient(targetPlayer)
GetMouseResponse.OnServerEvent:Connect(function(player, mouse)
if player == targetPlayer then
mouse = mouse
end
end)
-- Client
GetMousePing.OnClientEvent:Connect(function()
GetMouseResponse:FireServer(game.Players.LocalPlayer:GetMouse())
end)
You will need to adjust this for your needs, but this is the general pattern. PS: Do not use remote functions if you are communicating S → C → S, because the player could simply leave and the server script would keep waiting for an answer, and that’s only one of the problems that you would encounter.
Server:
local mouse
game.ReplicatedStorage.Storage.Events.getMouse:FireClient(plr)
game.ReplicatedStorage.Storage.Events.getMouseResponse.OnServerEvent:Connect(function(tplr, m)
if tplr == plr then
mouse = m
end
end)
print(mouse.Hit.Position)
Client:
game.ReplicatedStorage.Storage.Events.getMouse.OnClientEvent:Connect(function()
local m = game.Players.LocalPlayer:GetMouse()
game.ReplicatedStorage.Storage.Events.getMouseResponse:FireServer(m)
end)
It did not work.
attempt to index nil with 'Hit'
Yes, because you are printing the mouse immediately. Put the print after mouse = m
.
Please, don’t use RemoteEvents
in order to return data from the server to the client et vice-versa. You should look into RemoteFunctions.
-- server script
local RemoteFunction = (REMOTEFUNCTION)
local pieMultipliedBy2 = RemoteFunction:InvokeClient(player, 3.14, "hello world") -- sends info to client
print(pieMultipliedBy2)
-- local script
local RemoteFunction = (REMOTEFUNCTION)
local function getInfoLol(pie, name)
local newNumb = pie*2
warn(name)
return newNumb -- returns pie multiplied by 2 back to the server
end
RemoteFunction.OnClientInvoke = getInfoLol -- connects the function
By the way, if the player leaves mid-invoke, both the server and the client will error, so I’d recommend you to use pcalls in order to avoid these errors.
Ok but how can i use the returned value in the server script?
You can save this data using a variable, using local
.
I am using
local mouse = game.ReplicatedStorage.Storage.Events.getMouse:InvokeClient(plr)
print(mouse.Hit.Position)
yet it still doesn’t work.
attempt to index nil with 'Hit'
Client:
local function getMouse()
local mouse = game.Players.LocalPlayer:GetMouse()
return mouse
end
game.ReplicatedStorage.Storage.Events.getMouse.OnClientInvoke = getMouse
why not pack the mouse info into a table so you don’t have to try to send an object that I believe only exists on the client to the server?
game.ReplicatedStorage.Storage.Events.getMouse.OnClientInvoke = function()
return game.Players.LocalPlayer:GetMouse().Hit
end
Can’t you just return the Hit
instead of the entire mouse? I think that might work out.
Ok, it worked this way, thanks!
This method with pcalls is not bulletproof either. Exploiters can modify the local script so it waits forever and never returns a value. That would also stop the server. You should never ever rely on the client.
I know you should never trust the client, but you can code a script that tells the server that if it waited long enough without receiving a response, it must shut it off.
Also, you can wrap the entire function inside a coroutine so it doesn’t stop the main routine.
Yes, but at that point, it’s simpler to just use two events.
I disagree, using 2 RemoteEvents or even just 1 would be a lot better here. Having the client need to return in a RemoteFunction is just a bad idea, exploiters can easily abuse it.
Using a coroutine is just a waste of performance when you can easily avoid it by just using Events.