Hello! I am Domderp999, advanced builder, and a beginner Scripter. I need help finding what Is wrong with this code. I have made it, so that when you touch a a part, it would call an event from the server to the client, and tell it to enable a GUI (FOR THE CLIENT). But, it doesn’t seem to work. I have also checked the output, nothing is coming in there. Here are some of the images of the code I have written:
Server Scripts don’t run when they aren’t parented to ServerScriptService or Workspace. Switch it with a LocalScript and see what happens.
Edit: OnClientEvent is an event that can only be fired in LocalScripts, so you’d have to switch it with a LocalScript for these two reasons.
Double Edit: You also have to put a player instance in the parenthesis in FireClient(). The player instance in it will be the player that it will fire for.
The script with the onclientevent should be a local script. And the other issue is what others have said
FireClient() needs a Player as argument, making it look like this
How you get the player is another story.
:FireClient's first argument needs a player to fire to. Otherwise Roblox won’t know who to work with.
You need to pass a player instance when you call FireClient.
script.Parent.Touched:Connect(function(hit) local player = game.Players:GetPlayerFromCharacter(hit.Parent) if (player) then game.ReplicatedStorage.RemoteEvent:FireClient(player) end end)
First of all, the script inside the GUI has to be a local script as only local scripts make changes on the client,
Second of all, you have to pass the player as an argument when firing client. This is how you can get the player:
script.Parent.Touched:Connect(function(hit) local human = hit.Parent:FindFirstChild("Humanoid") -- You don't want to fire client when the part that is touching is not a player if human then -- Getting the player using the "GetPlayerFromCharacter" function, the first argument has to be the character local player = game.Players:GetPlayerFromCharacter(hit.Parent) game.ReplicatedStorage.RemoteEvent:FireClient(player) end end
Lastly, what you wrote in the script inside the GUI is correct, just change it to a local script.
First of all, please, for god’s sake, paste your code here like this:
All right, here are a two reasons why your code is not working:
Regular scripts only detect
OnServerEvent. You need to put the GUI enabling function into a LocalScript.
Server sees a lot of clients. Every player in the game is a client visible to server. When you
FireClient() without an argument, server is confused because there are multiple clients. Server code should look like this:
script.Parent.Touched:Connect(function(part) if game.Players:GetPlayerFromCharacter(part.Parent) then --checks if we can get a player from the part game.ReplicatedStorage.RemoteEvent:FireClient(game.Players:GetPlayerFromCharacter(part.Parent)) end)
Even cooler code with only 1 script
Since you can get player from their character and every player has PlayerGui, this task can be done with only 1 server-sided script parented to a part that needs to be touched:
script.Parent.Touched:Connect(function(part) local player = game.Players:GetPlayerFromCharacter(part.Parent) --we retrieve the player if player then --checks if we actually did that player.PlayerGui.Delivery.Enabled = true --enables the GUI end end)
onclientevent can only be invoked by localscripts, also fireclient needs a player instance to actually fire
(also is that comic sans in script? jesus)
I’m confused as to why you can’t have this whole thing in a local script. In fact, it would be much more efficient for your use case.
OnClientEvent doesn’t work in scrips because LocalScripts can only handle that event. You should also avoid using server scripts on the client but instead use LocalScripts for client sided things because server scrips should be used on the server. You should carefully read over this developers hub article about RemoteEvents and RemoteFunctions to get a better idea of how they work: Remote Functions and Events
I think you are over complicating everything with involving the server because believe it or not you can use the touched event on the client in a LocalScript. Any sort of client sided input or client sided interaction should be handled on the client in a LocalScript. Then when it is time for the server to get involved you then do the required sanity checks on the server.
For your use case you should change the script under the ScreenGui to a LocalScript and paste this code inside it:
local WorkActivate = workspace.WorkActivate WorkActivate.Touched:Connect(function() script.Parent.Enabled = true end)
The code above will work purely on the client without the involvement of the server.