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
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 referencingLocalPlayer 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.
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.
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: 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)