Hello, I made a Touch Event that whenever the player's character touches the part, it will fire a RemoteEvent. Easy right? Wrong. I put the FireServer script in a local script because Firing the server only works on clients.
FireServer Local Script:
1 | script.Parent.Touched:Connect( function (hit) |
2 | if hit.Parent:FindFirstChild( "Humanoid" ) then |
3 | game.ReplicatedStorage.ShowCodeGUI:FireServer() |
4 | end |
5 | end ) |
OnServer Script:
1 | game.ReplicatedStorage.ShowCodeGUI.OnServerEvent:Connect( function (player) |
2 | local playerGUI = player:WaitForChild( "PlayerGui" ) |
3 | local CodeFrame = playerGUI:FindFirstChild( "CodeGUI" ):FindFirstChild( "CodeFrame" ) |
4 | CodeFrame.Visible = true |
5 | end ) |
Also CodeGUI is located in StarterGUI, meaning it will get cloned and will be located in Player's PlayerGUI.
You can't insert a LocalScript
inside a Part, instead please move your LocalScript
to StarterGui
And please replace
1 | script.Parent.Touched |
To:
1 | game.Workspace.PartName.Touched |
This must work though.
(read the code as tl;dr srry i put max effort on everything)
According to the Wiki page on LocalScript, your FireServer script will not run since it is parented to a part which, I assume, is not a descendant of the player's client-side services.
Solution 1
Perhaps you could flip things around - FireServer will be ran on the server, whilst the player's client will be handling the event. By then, you can spend a minute on readjusting how the scripts will have to function for them to properly handle the event, such as switching from :FireServer()
to :FireClient(plr)
, etc.
01 | --[[ |
02 | FireServer but it's a normal Server Script |
03 | Its Parent is still the same doe |
04 | ]] |
05 | local players = game.Players |
06 |
07 | script.Parent.Touched:Connect( |
08 | function (hit) |
09 | --You definitely need to run a Player check here instead of checking for Humanoid |
10 | local parent = hit.Parent |
11 | local plr = players:GetPlayerFromCharacter(parent) |
12 | if plr then --If player exists then |
13 | --Fire the event to the target's client. |
14 | game.ReplicatedStorage.ShowCodeGUI:FireClient(plr) |
15 | end |
16 | end |
17 | ) |
01 | --[[ |
02 | OnServer but it's a LocalScript |
03 | Its Parent is the CodeGUI itself to make things ez |
04 | ]] |
05 | local player = game.Players.LocalPlayer |
06 |
07 | game.ReplicatedStorage.ShowCodeGUI.OnClientEvent:Connect( function () |
08 | --I leave these here in case this script's Parent isn't CodeGui |
09 | --local playerGUI = player:WaitForChild("PlayerGui") |
10 | --local CodeFrame = playerGUI:FindFirstChild("CodeGUI"):FindFirstChild("CodeFrame") |
11 |
12 | local CodeFrame = script.Parent:FindFirstChild( 'CodeFrame' ) |
13 | CodeFrame.Visible = true |
14 | end ) |
Solution 2
But if for some reasons, you wanna keep FireServer... local, then you can change the parent of the FireServer script to somewhere else the script can run in, as the Roblox Wiki has enlisted. Once it is changed, create a variable as a reference to the part in you needs, and change things up a little bit:
01 | --[[ |
02 | FireServer LocalScript (Put this in anywhere the script runs such as StarterPlayerScripts) |
03 | ]] |
04 | --Add a reference variable to the part you wanna check. |
05 | local partToCheck = workspace.ExamplePart --Your part |
06 |
07 | partToCheck.Touched:Connect( |
08 | function (hit) |
09 | --Maybe you wanna check for player instead? Check the one above, then I'll leave that to ya |
10 | if hit.Parent:FindFirstChild( "Humanoid" ) then |
11 | game.ReplicatedStorage.ShowCodeGUI:FireServer() |
12 | end |
13 | end |
14 | ) |
Do NOT waste remotes on touch events.
I added debounce and some extra protection so it doesn't overload the character with guis, and theres now a cooldown. feel free to set the "cooldown" variable to 0 if you dont want a cooldown at all
Here it is; editing is required to make it work.
01 | local function insert(player) |
02 | if player.PlayerGui:FindFirstChild( 'gui name' ) then return end |
03 | -- add gui insert code!! |
04 | end |
05 |
06 | local cooldown = 2 |
07 | local cooldown_ = false |
08 |
09 | local part = script.Parent |
10 | part.Touched:Connect( function (hit) |
11 |
12 | if cooldown_ then return end -- debounce |
13 |
14 | if game.Players:FindFirstChild(hit.Parent.Name) and hit.Parent:FindFirstChild( 'Humanoid' ) then |
15 | cooldown_ = true |
16 | insert(game.Players:FindFirstChild(hit.Parent.Name)) |
17 | wait(cooldown) |
18 | cooldown_ = false |
19 | end |
20 | end ) |
It's MUCH more convenient, and Touched events can be used on Server & Client.
(Not trying to be rude and all, but) please do a bit more research before you post a silly question. Remotes should only be used when required, like for sending a lot of data to the server, etc.
I hope this helps you!