What does "attempt to index nil with 'WaitForChild'" mean? - lua

script.Parent.MouseButton1Click:connect(function()
local RS = game:GetService("ReplicatedStorage")
local item = RS:WaitForChild("Pencil")
local price = 350
local player = game.Players.LocalPlayer
local stats = player:WaitForChild("leaderstats")
if stats.Strength.Value>=price then
stats.Strength.Value = stats.Strength.Value - price
local cloned = item:Clone()
cloned.Parent = player.Backpack
cloned.Parent = player.StarterGear
end
end)
I am trying to make a shop and it comes up with "attempt to index nil with 'WaitForChild'" on line 6:
local stats = player:WaitForChild("leaderstats")
I copied it exactly how the video had it and the video had no problem and apparently player has no value even though we set it up just one line above

It means that you are indexing a nil value, which means that player value is nil, which means that game.Players.LocalPlayer on the previous like returns nil. Why that is you need to figure out, as there is not much to go by.
The example shows that it should be local player = game:GetService("Players").LocalPlayer, so you may want to try that.

Related

"Attempt to call a nil value" with data stores

I called the moduleScript and I did everything correctly I think
I also tried with a normal script but it didnt work
Pls help I tried lots of things but nothing works Im creating a new game and I cant continue the game because the data doesnt save
Im putting so much text because if not I cant publish this :)
local PlayerStatManager = {}
local DataStoreService = game:GetService("DataStoreService")
local playerData = DataStoreService:GetChildren("DataPlayer")
game.Players.PlayerAdded:Connect(function(player)
local stats = Instance.new("Folder")
stats.Parent = player
stats.Name = "leaderstats"
local clicks = Instance.new("NumberValue")
clicks.Name = "Clicks"
clicks.Parent = stats
local coins = Instance.new("NumberValue")
coins.Name = "Coins"
coins.Parent = stats
local rebirths = Instance.new("NumberValue")
rebirths.Name = "Rebirths"
rebirths.Parent = stats
local id = player.UserId
clicks.Value = playerData:GetAsync(player.UserId)
end)
game.Players.PlayerRemoving:Connect(function(player)
local id = player.UserId
playerData:SetAsync(id, player.leaderstats.Clicks.Value)
end)
return PlayerStatManager
local playerData = DataStoreService:GetChildren("DataPlayer")
This line causes the problem.
First of all, GetChildren doesn't get a child of an instance, it returns an array-like table of all children. In that case, FindFirstChild makes more sense.
Well, even FindFirstChild isn't correct! DataStoreService shouldn't have any children - if it does, you shouldn't care about them. You probably wanted to use GetDataStore.
About the error message, it says that you're trying to call a nil value, which means that you're trying to call something that doesn't exist. It's this line that causes the error:
clicks.Value = playerData:GetAsync(player.UserId)
You are using GetChildren, which returns a table. playerData is a table. You're trying to get GetAsync and then call it. In the table, we don't have the key GetAsync (we only have number keys, because it's an array-like table). So you're trying to call a nil value.

Why is 'player' returning nil?

It keeps returning nil for player and saying that im trying to index a nil with 'WaitForChild' even though I have tried adding a wait command and changing player to 'game.Players.LocalPlayer' I'm new to scripting and I don't know what else to do.
local buyButton = script.Parent
local player = game:GetService("Players").LocalPlayer
local multiplier = player:WaitForChild("Multiplier")
buyButton.MouseButton1Up:Connect(function()
if multiplier.Value == 0 then
multiplier.Value = 1
end
end)
Instead of local player = game:GetService("Players").LocalPlayer you want to do:
local players = game:GetService("Players")
local player = players.localplayer

Set username/userID to boat when seat is occupied

I am working on a game in which you can sail with boats. My script works but I wonder if I am doing it right?
What I'm trying to do is that as soon as you spawn a boot the name of the boot is the userID + the name of the ship.
This works fine thanks to one guy on this forum (Much Love)!
So now I wanted to write a script inside the seat as soon as another player or the player himself sits on the chair changes the name of the boat to that player name + boat name. This works, but now I have managed to get the name of the player and not his id. I prefer the ID of the player. How do you do that?
Because I get the player name instead of his id. I had to make another check to see if the boat does not already exist. Now 1 player can get 2 boats because player.Name and player.UserID do not match.
So my question is how do I get the userID instead of its name from the script below so that a player can take over the boat but not get 2 boats in the end?
I'm sorry for my bad coding i'm new to this :) Thanks for helping out!
Script inside of seat:
local Seat = script.Parent
local debounceCheck = false
local ChangeBoatName = script.Parent.Parent
local boatname = "ShipOnePerson"
Seat.Changed:Connect(function(player)
if Seat.Occupant ~= nil then
if Seat.Occupant.Parent.Name ~= "PlayerNameHere" then
local PlayerToNewBoat = game.Players:FindFirstChild(Seat.Occupant.Parent.Name)
local Character = PlayerToNewBoat.Character or PlayerToNewBoat.CharacterAdded:Wait()
if not debounceCheck then
-- Is it Occupant?
debounceCheck = true
-- Mark it as Occupant, so that other handlers don't execute
if ChangeBoatName then
local plruserid = Seat.Occupant.Parent.Name
local SetNameToBoat = plruserid..boatname
local NewBoat = ChangeBoatName
NewBoat.Name = SetNameToBoat
NewBoat.Parent = game.Workspace
print(NewBoat)
end
end
else
debounceCheck = false
-- Mark it as not Occupant, so other handlers can execute again
end
else
debounceCheck = false
-- Mark it as not Occupant, so other handlers can execute again
end
end)
My second question is how can I make sure that as soon as you press the button RegenButton it first checks if there is already a boat in that place and if so how do I make sure that you cannot spawn?
Below is the code that is in the button regenbutton
local cd = workspace.Regenbutton:WaitForChild('ClickDetector')
local boat = game:GetService('ServerStorage'):WaitForChild('ShipOnePerson')
local button = workspace:WaitForChild('Regenbutton')
local debounce = false
local boatname = "ShipOnePerson"
cd.MouseHoverEnter:Connect(function()
button.Transparency = 0.5
end)
cd.MouseHoverLeave:Connect(function()
button.Transparency = 0
end)
cd.MouseClick:Connect(function(player)
local plruserid = player.UserId
local SetNameToBoat = plruserid..boatname
local plrextraboat = player.Name..boatname
print(SetNameToBoat)
local oldboat = workspace:FindFirstChild(SetNameToBoat)
local oldboat2 = workspace:FindFirstChild(plrextraboat)
if not debounce then
if oldboat then
oldboat:destroy()
end
if oldboat2 then
oldboat2:destroy()
end
debounce = true
local NewBoat = boat:Clone()
NewBoat.Name = SetNameToBoat
NewBoat.Parent = game.Workspace
wait(5)
debounce = false
end
end)
So my question is how do I get the userID instead of its name
Instead of Player.Name use Player.UserId
My second question is how can I make sure that as soon as you press the button RegenButton it first checks if there is already a boat in that place and if so how do I make sure that you cannot spawn?
You could use Instance.GetChildren to get a list of all children, then iterate over that list in a loop. Check wether any of those children is a boat Instance.IsA and if so, check whether it is in the spawn location.

"Unable to cast value to Object" error message

So I am using a remote function, as seen at the end, and for some reason, a normal assignment of a variable won't work, it is giving me the error message, "Unable to cast value to Object," what is wrong?
local storeEvent = script.Parent.Parent.OpenStore
local slotNum = 1
script.Parent.Touched:Connect(function (hit)
if game.Players:GetPlayerFromCharacter(hit.Parent) then
storeEvent:InvokeClient(slotNum)
end
end)
and connecting to the other script:
script.Parent.OnInvoke:Connect(function (slot)
local StoreArrows = game.ReplicatedStorage.StoreArrows
StoreArrows.SlotNum.Value = slot
local cam = game.Workspace.Camera
local storeButtons = script.Parent
local camNum = game.ReplicatedStorage.StoreArrows.CamNum.Value
local camNumInst = game.Workspace.CamStorage:WaitForChild("Cam-"..camNum)
cam.CameraType = Enum.CameraType.Scriptable
cam.CFrame = camNumInst.CFrame
local clonedStoreButtons = StoreArrows:Clone()
clonedStoreButtons.Parent = player.PlayerGui.ScreenGui
end)
Keep in mind that many clients connect to a server at a time. So when you call a RemoteEvent's InvokeClient function, you have to tell it which client to invoke it on. The first parameter to InvokeClient is supposed to be the player, that's why the error is telling you that it cannot cast the slotNum value to a player object.
local storeEvent = script.Parent.Parent.OpenStore
local slotNum = 1
script.Parent.Touched:Connect(function(hit)
-- check that the thing that we touched is actually a player
local player = game.Players:GetPlayerFromCharacter(hit.Parent)
if player then
-- tell that player to open the store
storeEvent:InvokeClient(player, slotNum)
end
end)

Roblox Error: attempt to index local 'screengui' (a nil value)

Workspace.Part.Script:16: attempt to index local 'screengui' (a nil value)
wait(2) -- Testing to make sure assets loaded
script.Parent.Touched:connect(function(hit)
if not hit or not hit.Parent then return end
local human = hit.Parent:findFirstChild("Humanoid")
if human and human:IsA("Humanoid") then
local person = game.Players:GetPlayerFromCharacter(human.parent)
if not person then return end
person.Checklist.FirstEggCollected.Value = true
local playgui = person:FindFirstChild('PlayerGui')
print(playgui)
wait(0.2)
local screengui = playgui:FindFirstChild('ScreenGui')
wait(0.2)
print(screengui) -- This prints nil
local collectnotice = screengui:FindFirstChild('CollectionNotice') -- This is line 16
local Toggle = collectnotice.Toggle
local text = Toggle.Text
local value = text.Value
value = "The Easy Egg!"
person:WaitForChild('PlayerGui'):FindFirstChild('ScreenGui'):FindFirstChild('CollectionNotice').Toggle.Color.Value = Color3.fromRGB(0,255,0)
person:WaitForChild('PlayerGui'):FindFirstChild('ScreenGui'):FindFirstChild('CollectionNotice').Toggle.Value = true
script.Parent:Destroy()
wait(5)
game.Workspace.Variables.IfFirstEggInGame.Value = false
end
end)
I've been at this for hours. No idea how to make the error fix. FE is on, Yes its name is "ScreenGui" and it is inside "PlayerGui"
Error: Workspace.Part.Script:16: attempt to index local 'screengui' (a nil value)
From the Roblox manual: http://wiki.roblox.com/index.php?title=API:Class/Instance/FindFirstChild
Description: Returns the first child found with the given name, or nil
if no such child exists.
So there seems to be no child named "ScreenGui".
If a function may return nil you have to handle that properly. Blindly indexing possible nil values is bad practice.
Your issue is at the line local collectnotice = screengui:FindFirstChild('CollectionNotice').
You do not have an instance listed for the screengui variable.

Resources