I get an error, but I don't know how to fix it

I’m making a task system. But basically, I get this error…anyone know how to fix it?

Workspace.Cabin.Walls.Hitbox.FixScript:3: attempt to index nil with ‘Backpack’

local player = game.Players.LocalPlayer
local hitbox = script.Parent
local hammer = player.Backpack:WaitForChild("Hammer")
local repairLog1 = workspace.Cabin.Walls.RepairLog1
local repairLog2 = workspace.Cabin.Walls.RepairLog2
local repairLog3 = workspace.Cabin.Walls.RepairLog3

hammer.Activated:Connect(function(player)
	hitbox.Touched:Connect(function(hammer)
		repairLog1.Transparency = 0
		repairLog1.CanCollide = true
		repairLog2.Transparency = 0
		repairLog2.CanCollide = true
		repairLog3.Transparency = 0
		repairLog3.CanCollide = true

		game.StarterGui.ScreenGui.Frame.Task2.Completed = true
		game.StarterGui.ScreenGui.Frame.Task2.Bar.Transparency = 0
		
		hammer:Destroy()
	end)
end)
2 Likes

If your script is running from the workspace, it’s a Script. You can only access the LocalPlayer from a LocalScript.

1 Like

Players.LocalPlayer is a client-sided property. It is used to access the Player instance of the client whose machine a LocalScript is running on. Since the server is not a human-being with a Roblox account, there is no Player instance that belongs to it. Players.LocalPlayer will read nil on the server.

Furthermore, StarterGui is not where the active user interface resides. It is simply a storage container. Each player has their own monitor and own interaction with a game’s UI, so each player needs their own copy. The active UI of a client resides in a special folder under their Player instance called “PlayerGui”. You will need to access that folder to see changes at runtime.

On another note, you’re embedding events, which have a high likelihood of causing memory leaks and consequential multiplicative behaviour. Your code is one of these cases. You will need to actively manage the BasePart.Touched connection to ensure it does not persist or duplicate

1 Like

the gui thing doesn’t matter bc it’s a 1 player game

1 Like

It does matter.

“to see changes in runtime”

Accessing the StarterGui in any scenario is not okay when intending to interact with the runtime user interface

1 Like

how could i fix the script to make it work?

1 Like

even if the gui is always visible for the player??

1 Like

Yes. The GUIs the player sees are not the instances in StarterGui

2 Likes

so how can I fix it to make it work?

1 Like

To reference the Player’s Gui, you need to access their PlayerGui.

This is how you do it, assuming our player variable is a Player instance

player.PlayerGui

In your case, you’d do the following:

player.PlayerGui.ScreenGui.Frame.Task2.Completed = true
player.PlayerGui.ScreenGui.Frame.Task2.Bar.Transparency = 0

One thing I would also suggest is to create a variable referencing your frames so that you don’t have to constantly write out those long lines.


Alongside this, make sure you are referencing LocalPlayer on a LocalScript. If you aren’t, either move your code to a LocalScript or, if this has to be on the server, account for the script not being on the client by referencing a specific Player.

1 Like

Ok so I am really confused.

Is your script a server script or a local script?

If this is a server-script, from what people are saying I assume so, you can’t access the player via localplayer. You don’t need to anyway, as you’ve already defined the player in the .Activated event.

I recommend adding some form of yield like task.wait to prevent the script from going haywire. .Touched is extremely sensitive.

Lastly, you can not access the player’s Gui via ScreenGui. You’re confusing ScreenGui with PlayerGui: player.PlayerGui. In my experience you should use RemoteEvents instead, and listen for an event to change it from there.

this is a server script in the hitbox

I changed it to player.PlayerGui
but my main issue is this error

Workspace.Cabin.Walls.Hitbox.FixScript:3: attempt to index nil with ‘Backpack’

This will work if there is only one player in your game:

local player = game.Players:FindFirstChildOfClass("Player")
local hitbox = script.Parent
local hammer = player.Backpack:WaitForChild("Hammer")
local repairLog1 = workspace.Cabin.Walls.RepairLog1
local repairLog2 = workspace.Cabin.Walls.RepairLog2
local repairLog3 = workspace.Cabin.Walls.RepairLog3

hammer.Activated:Connect(function(player)
	hitbox.Touched:Connect(function(hammer)
		repairLog1.Transparency = 0
		repairLog1.CanCollide = true
		repairLog2.Transparency = 0
		repairLog2.CanCollide = true
		repairLog3.Transparency = 0
		repairLog3.CanCollide = true

		game.StarterGui.ScreenGui.Frame.Task2.Completed = true
		game.StarterGui.ScreenGui.Frame.Task2.Bar.Transparency = 0
		
		hammer:Destroy()
	end)
end)

I think you said it was single player right?

As I’ve said before, you can’t access the player via LocalPlayer if it’s in a server-script. LocalPlayer is a variable only reserved for the client e.g. StarterPlayerScripts, StarterCharacterScripts, StarterGui (PlayerGui), and StarterPack.

It seems like you’re trying to code the hammer, but in third-person, so to speak. I recommend moving this script to the tool itself, and turning it into a LocalScript.

Here’s a visualization:
image
You don’t have to put the hammer in starterpack, it’s just an example.

The updated code will look like:

local player = game.Players.LocalPlayer
local playerGui = player.PlayerGui
local Task2 = playerGui:FindFirstChild("ScreenGui").Frame.Task2

local hitbox = ? -- I don't know where this is.
local hammer = script.Parent

local Cabin = workspace:WaitForChild("Cabin")
local repairLog1 = Cabin.Walls.RepairLog1
local repairLog2 = Cabin.Walls.RepairLog2
local repairLog3 = Cabin.Walls.RepairLog3

hammer.Activated:Connect(function() -- no need to define the player
       hitbox.Touched:Connect(function() -- hammer won't do anything as a parameter
        repairLog1.Transparency = 0
		repairLog1.CanCollide = true
		repairLog2.Transparency = 0
		repairLog2.CanCollide = true
		repairLog3.Transparency = 0
		repairLog3.CanCollide = true

        Task2.Completed = true
        Task2.Bar.Transparency = 0
    end)
end)

you are right it is a one player game

so, I already coded the hammer but I’m trying to make a wall that you fix when you hit with the hammer

Can you show me where hammer (and it’s scripts) are located?

well, it’s in server storage but the player does not start with the hammer. They have to get the hammer from a hammer spawner
Screenshot 2025-02-24 134005