I am making a tool giver surface gui that gives tools by a button on a surfaceGUI. Here is a photo of the path of it.
Inside the frame, There is a TextButton and other things, The textbutton has a localscript that detects the button click, and gives the tool from the ServerStorage. Here is a image:
The local script is:
local toolName = "ToolName" -- Tool that has to be given from ServerStorage
-- Function to give the tool to a player
local function giveTool(player)
local playerBackpack = player:FindFirstChild("Backpack")
local tool = game.ServerStorage:FindFirstChild(toolName)
if playerBackpack and tool then
local toolClone = tool:Clone()
toolClone.Parent = playerBackpack
print(player.Name .. " received " .. toolName)
end
end
-- Handle button clicks
local function onButtonClicked(player)
giveTool(player)
end
-- Connect button clicks to the onButtonClicked function
local surfaceGui = script.Parent:FindFirstChild("SurfaceGui")
if surfaceGui then
for _, frame in ipairs(surfaceGui:GetDescendants()) do
if frame:IsA("TextButton") then
frame.MouseButton1Click:Connect(function()
local player = game.Players:GetPlayerFromCharacter(frame.Parent.Parent.Parent.Parent)
if player then
onButtonClicked(player)
end
end)
end
end
end
Please help me, as it is not giving the tool to me, Here is a photo of how the surfaceGUI Tool Giver Looks:
LocalScripts under no circumstance execute in Workspace. What you can do is instead create a Script with ClientRunContext and paste the code from your LocalScript in it.
At first, how AlternativeOrNot said upper you need to do Script instead of LocalScript (Local script cant reach ServerStorage and ServerScriptService), second i dont see where are variable toolName is updated.
Yep, unfortunately the other answers were not right.
There is no way to make a SurfaceGUI (or Billboard GUI) with a button in the workspace.
You need to have it in the PlayerGUI, and then change the Adornee to the spot you want it to display at. This also saves quite some rendering when you have multiple copies luckily.
Keep in mind you will need to connect a RemoteEvent from the button click within the PlayerGUI to a server script.
i don’t agree with that you cannot use TextButtons in Surface/Billboard GUI.
TextButtons will be visible in the Surface/Billboard GUI when they’re located in workspace and you’re able to make any functions to the TextButton but if you want to make them locally then you must have used local script that does handle click detect to your TextButton.
other way, if Player has this Surface/Billboard GUI, you can use Adornee property to attach GUI to the part, however, it looks awkward when every Player has this Surface/Billboard GUI .
so it would be enough, if Surface/Billboard GUI is located in workspace
apparently, local script do not run in workspace, they can run if they are located in specific directory, which list given in the local script documentation.
e.g. you can make a local script in Player object that will handle interactions with the main Surface/Billboard GUI that is located in workspace.
Try changing the local script to a script and set the script RunContext to “Client”
local player = game.Players.LocalPlayer -- the player
local toolName = "ToolName" -- Tool that has to be given from ServerStorage
-- Function to give the tool to a player
local function giveTool()
local playerBackpack = player:FindFirstChild("Backpack")
local tool = game.ServerStorage:FindFirstChild(toolName)
if playerBackpack and tool then
local toolClone = tool:Clone()
toolClone.Parent = playerBackpack
print(player.Name .. " received " .. toolName)
end
end
-- Connect button clicks to the onButtonClicked function
local surfaceGui = script.Parent:FindFirstChild("SurfaceGui")
if surfaceGui then
for _, frame in ipairs(surfaceGui:GetDescendants()) do
if frame:IsA("TextButton") then
frame.MouseButton1Click:Connect(function()
giveTool()
end)
end
end
end
Also, I forgot to mention that clients can’t access ServerStorage. You’ll need to create an additional folder in ReplicatedStorage and name it ‘Storage’ or something. Then, change this
local tool = game.ServerStorage:FindFirstChild(toolName)
to
local tool = game.ReplicatedStorage.Storage:FindFirstChild(toolName)