So, when I try to clone a GUI into a player, it works, but it gives me an error. Here is the code:
function touch(hit) if hit.ClassName == "Part" then local char = hit.Parent local plr = game.Players:GetPlayerFromCharacter(char) if plr.PlayerGui:FindFirstChild("BSGui") == nil then local gui = game.Lighting.BSGui:Clone() gui.Parent = plr.PlayerGui end end end script.Parent.Touched:connect(touch)
Error: Workspace.BSmith_Trigger.Script:5: attempt to index global 'plr' (a nil value) 18:11:53.758 - Stack Begin 18:11:53.758 - Script 'Workspace.BSmith_Trigger.Script', Line 5 18:11:53.759 - Stack End
Cleaning up your code
A significant difference I'd like to point out here, would be cleaning up this code a little bit. As I always say, if you want your program to respect you, you have to respect it. This should be your revised version of your code, minus some details I'll go over in a second.
-- Declaring services at the beginning of your script local players = game:GetService("Players") local lighting = game:GetService("Lighting") -- Taking away the need to declare a function, by connecting an anonymous function straight into the event. script.Parent.Touched:connect(function(obj) -- No need to check if it's a part, since only parts can physically touch other parts. local char = obj.Parent local player = players:GetPlayerFromCharacter(char) -- We need to check if the player actually exists before resuming our code. What if something that's not a player touched the part? if player then -- Createing a reference to the PlayerGui local playergui = player.PlayerGui -- Check to see if there's no GUI named BSGui if not playergui:FindFirstChild("BSGui") then -- If there isn't, then clone it. lighting.BSGui:Clone().Parent = playergui end end end)
Also notice how I indented my code to it's appropriate scope
. This might not seem like a big deal, but it's very important to visually see the structure of your code.
Better solutions
I'd also strongly recommend not using the Lighting
service to store items, as this method has been replaced for quite a while with ServerStorage
and ReplicatedStorage
. Using either of these storages should be fine for what you're trying to do with them.
The first solution is a good substitute for your code, but I feel he neglected to explain why your code didn't work.
In your code, you set plr, to the value of the player whose character touched it. This would be "perfect" if it was guaranteed that only players touched it. The fault in your code is the real game application for instances where the game could not detect a player from the touched object. Always keep in mind what your code is supposed and where errors could arise. Generally, you don't want a nil value.