What do you want to achieve?
I would like to make a gui shirt giver
What is the issue?
I tried using this script:
script.Parent.MouseButton1Click:Connect(function(player)
local shirtId = "http://www.roblox.com/asset/?id=3007867264"
local char = player.Character or player.CharacterAdded:Wait()
char.Shirt.ShirtTemplate = shirtId
end)
the script is normal script in TextButton
and error appeared in output as: attempt to index nil with ‘Character’
I am new to Lua scripting and I would like some help as I do not understand what’s wrong with my scipt right now. Thank you in advance.
the MouseButton1Click event doesn’t pass the player as an argument, use
local player = game.Players.LocalPlayer -- the service will always exist at this point, since the local script will replicate after- GetService() is still canonical for getting services though
local char = player.Character or player.CharacterAdded:Wait()
script.Parent.MouseButton1Click:Connect(function()
local shirtId = "http://www.roblox.com/asset/?id=3007867264"
local player = game.Players.LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()
char.Shirt.ShirtTemplate = shirtId
end)
But it still getting atempt to index nil with ‘Character’
Make sure this is in a LocalScript rather than a regular script.
local Players = game:GetService('Players')
local player = Players.LocalPlayer
local shirtId = "http://www.roblox.com/asset/?id=3007867264"
script.Parent.Activated:Connect(function()
local char = player.Character or player.CharacterAdded:Wait()
local shirt = char:FindFirstChild('Shirt') or Instance.new('Shirt', char)
shirt.ShirtTemplate = shirtId
end)
The reason is that If you use a ‘regular’/ server - script under StarterGui, then eventually it’ll be replicated under every player’s PlayerGui, the server won’t know about the script’s existence and the code in said script won’t run.
One thing to note; as far as I’m aware, changing the shirt on the client won’t replicate to the server. If you need it to replicate to the server (letting every client see that your shirt changed), let me know!
Just clarifying things, don’t call WaitForChild() on anything under Replicated Storage unless it’s guaranteed the script you’re calling from will be replicated first - it’s inefficient.
A debounce mechanism for the event firing would be good too, exploiters can spam remotes and crash servers.
First, you’ll slightly edit your LocalScript as follows:
local RS = game:GetService('ReplicatedStorage')
local shirtId = "http://www.roblox.com/asset/?id=3007867264"
local event = RS:WaitForChild('ShirtEvent')
script.Parent.Activated:Connect(function()
event:FireServer(shirtId) -- On this line, you can remove shirtId and simply define the id in the server script if you want to make this secure
end)
Then, you’ll make a Script inside of ServerScriptService like this:
local RS = game:GetService('ReplicatedStorage')
local event = RS:FindFirstChild('ShirtEvent') or Instance.new('RemoteEvent', RS)
event.Name = 'ShirtEvent'
event.OnServerEvent:Connect(function(player, shirtId) -- Once again, if needed you can simply define the id in this script to make it truly secure rather than depending on the id the client fires thru
local char = player.Character or player.CharacterAdded:Wait()
local shirt = char:FindFirstChild('Shirt') or Instance.new('Shirt', char)
shirt.ShirtTemplate = shirtId
end)
Using a local script might not be the best all of the time, so I use a server script for most of my GUI so it will be harder for hackers to hack my remote events. (Like a coin giver GUI or something of the sort)
Do note that an exploiter can easily fire a remote in a while loop and cause the server to perform too many actions, this would crash a server almost instantly.
@Itttikorn yes, resources exist scattered everywhere, older posts on the forum can help you learn too.