Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

How can I fix this error?

Asked by 8 years ago

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

2 answers

Log in to vote
3
Answered by 8 years ago

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.

Ad
Log in to vote
-2
Answered by 8 years ago

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.

Answer this question