I have fixed this but I need to know where the scripts go that Kiriot22 fixed to work with FE.
My Gui won't open when my part gets touched?
3 answers
There are multiple problems in your script
##Deprecated Functions
You use the method :findFirstChild(). This is deprecated, or not recommended to use. To change this is by changing your deprecated method to :FindFirstChild()
##You Should Use :WaitForChild() Instead of :FindFirstChild() If You Can
Speaking of :FindFirstChild(). You should use the method :WaitForChild(). WaitForChild's arguments are the part name and its optional argument, time out. The time out defaults to one second. WaitForChild() checks for the part you specify as usual, however, if that part is nil, it would wait the amount of time in the time out. If it couldn't find it still, it would warn and return an infinite yield. In contrary to :FindFirstChild(), it would error automatically if the argument specified is nil.
For example:
local brick = game.Workspace:FindFirstChild("Brick")
Since we have no part named "Brick" in Workspace, it would error However:
local brick = game.Workspace:WaitForChild("Brick")
It would wait for the amount of time in the timeout(remember, it defaults to one) and then warn
##Making Clean if-statements
What I mean by making clean if-statements includes not having lengthy conditionals and etc. But your if statements don't really have that problem. In the condition, if (human ~= nil) and debounce == false then, you can omit, or remove, the parenthesis and the ~= nil. This looks much more cleaner: if human and debounce == false then. This goes to another if-statement
##Extra Function
Your function, getPlayers(humanoid) is extra and unneeded. Instead, you can use hit to find the player by using the :GetPlayerFromCharacter() method. Your getPlayers(humanoid) works, but, it is just wastes your time when you could do all of that in one method.
##You Should Never Make Changes In StarterGui
What was a huge mistake in your script is that you have changed a GUI from StarterGui. This will not do anything because whatever in StarterGui will be cloned into PlayerGui(found in the player). How to fix this is by finding the PlayerGui in the player using :WaitForChild()
##Final Code Here is the final code. If you have noticed a few changes, please read the bottom, it might answer your question.
--\\ Touched Components
local part = script.Parent
local debounce = false
function onTouch(hit) -- I have changed "part" to "hit" because that fits much more better in here
local human = hit.Parent:WaitForChild("Humanoid") -- Gets humanoid
if human and debounce == false then -- Checks if humanoid is not nil
debounce = true
local player = players:GetPlayerFromCharacter(human.Parent) -- See, we used the :GetPlayerFromCharacter()! This simplifies your whole function
if player == nil then return end
local playerGui = player:WaitForChild("PlayerGui")
local shopGui = playerGui:WaitForChild("ShopGui")
local shopFrame = shopGui:WaitForChild("ShopFrame")
shopFrame.Visible = true
wait(2)
else
wait(2)
debounce = false
end
end
part.Touched:Connect(onTouch)
##How To Make This Script Compatible In Filtering Enabled
You have said that this script should be put into Filtering Enabled. I'll do that for you. You could pick the first answer and follow that, or, you could pick my answer.
Now, Filtering Enabled makes the server never trust the client. To make the server trust the client, we need to use Remote Events and Remote Functions to notify the server that it's not an exploit.
We will be using :FireClient() since our GUI is in the Client, not in the server.
What we will need to do first is to make our Remote Event. We will put this in ReplicatedStorage(this is important because we want the server and client to access it.). I will name the RemoteEvent to "FrameVisibleRemoteEvent".
Your Local Script in StarterGui should look like this:
--\\ Services
local repStorage = game:GetService("ReplicatedStorage")
local players = game:GetService("Players")
--\\ Player Components
local player = players.LocalPlayer
local playerGui = player:WaitForChild("PlayerGui")
--\\ GUI's
local shopGui = playerGui:WaitForChild("ShopGui")
local shopFrame = shopGui:WaitForChild("ShopFrame")
--\\ Network Data
local frameVisible = repStorage:WaitForChild("FrameVisibleRemoteEvent")
frameVisible.OnClientEvent:Connect(function()
shopFrame.Visible = true
end)
Your Server Script in you part should look like this:
--\\ Services
local repStorage = game:GetService("RepStorage")
--\\ Touched Components
local part = script.Parent
local debounce = false
--\\ Network Data
local frameVisible = repStorage:WaitForChild("FrameVisibleRemoteEvent")
function onTouch(hit)
local human = hit.Parent:WaitForChild("Humanoid") -- Gets humanoid
if human and debounce == false then -- Checks if humanoid is not nil
debounce = true
local player = players:GetPlayerFromCharacter(human.Parent)
if player == nil then return end
frameVisible:FireClient(player)
wait(2)
else
wait(2)
debounce = false
end
end
part.Touched:Connect(onTouch)
Now, the first answer that you have got in Filtering Enabled was a more general approach. My approach was very specific.
##PLEASE INDENT!
Indenting is crucial when typing clean code. You don't have to do this, however, if you wanted to come back to your code, you would be able to understand it. In contrary to not indenting, you might not be able to understand it.
5 comments
I just need this FE compatible, thanks though
You didn't state that your game is FE. I would've done that for you
Could you at least up-vote if it was a good answer?
Sorry about not replying for awhile, thanks for the answer, very much appreciated, I understand RemoteEvents a bit better since I've asked this question also, thanks again.
Your welcome
You mustn't use StarterGui for it. StarterGui contents get cloned to the player's PlayerGui. They are like a template. What you should do is set the visibility of the frame in PlayerGui instead.
Server script:
local remote = Instance.new("RemoteEvent", game.ReplicatedStorage)
remote.Name = "ToggleGui"
local debounce = false
function getPlayer(humanoid)
local players = game.Players:GetPlayers() --you should use GetPlayers() rather than GetChildren() or children()
for i = 1, #players do
if players[i].Character.Humanoid == humanoid then return players[i] end
end
return nil
end
function onTouch(part)
local human = part.Parent:findFirstChild("Humanoid")
if (human ~= nil) and debounce == false then
debounce = true
local player = getPlayer(human)
if (player == nil) then return end
remote:FireClient(plr, "ShopGui", true)
wait(2)
else
wait(2)
debounce = false
end
end
script.Parent.Touched:connect(onTouch)
Local script:
local plr = game.Players.LocalPlayer
local remote = game.ReplicatedStorage:WaitForChild("ToggleGui")
remote.OnClientEvent:Connect(function(name, bool)
local gui = plr.PlayerGui:FindFirstChild(name, true)
if gui then
gui.Visible = bool
end
end)
I edited the script to make it FE compatible.
3 comments
Thank you so much!
so do I put both in the part or one in serverscriptservice other in part?
You put the Server Script in the part and you put the Local Script any where the client can run (StarterGui,StarterPack etc.)
This works in Studio now but not in the real game, can someone please still help!?
local debounce = false
function getPlayer(humanoid)
local players = game.Players:GetPlayers() --you should use GetPlayers() rather than GetChildren() or children()
for i = 1, #players do
if players[i].Character.Humanoid == humanoid then return players[i] end
end
return nil
end
function onTouch(part)
local human = part.Parent:FindFirstChild("Humanoid")
if (human ~= nil) and debounce == false then
debounce = true
local player = getPlayer(human)
if (player == nil) then return end
player.PlayerGui.ShopGui.ShopFrame.Visible = true --this line, see?
wait(2)
else
wait(2)
debounce = false
end
end
script.Parent.Touched:connect(onTouch)
2 comments
If your game is FE, you need to use RemoteEvents for it to work. I edited my answer to make it FE compatible.
ok ty
This discussion is preserved as it was. New answers, comments, and votes are closed.

3 comments
It is "FindFirstChild." NOT "findFirstChild."
Instead of changing the GUI in StarterGui, change it in the player's PlayerGui, which can be accessed by user.PlayerGui. what the player sees on their screen are descendants of their playergui
Unless there are no players, getPlayer will return nil.