Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

Child Added won't fire unless I put in a wait? even though I used WaitForChild

Asked by 5 years ago

So i noticed that the child added function wasn't working for my backpack inside players


game.Players.PlayerAdded:Connect(function(plr) local Backpack = plr:WaitForChild("Backpack"); Backpack.ChildAdded:Connect(function() print('Some Thing was added') end) end)

Would return nothing in the output

but when I did this

game.Players.PlayerAdded:Connect(function(plr)
    wait(4)

    local Backpack = plr:WaitForChild("Backpack");

    Backpack.ChildAdded:Connect(function()

        print('Some Thing was added')

    end)


end)

it started printing things

Can someone explain to me why and how I can get around this?

0
I've always had problems with nested events, are you sure you can't just have a local script detect if something was put in the player's backpack when the player is already loaded into the server? SteamG00B 1633 — 5y
0
I can't because I need to save this in a datastore so I can reload it into the players backpack when they join later its like a inventory saving script I_UseAltAndVpn 47 — 5y

2 answers

Log in to vote
0
Answered by
karlo_tr10 1233 Moderation Voter
5 years ago

Very weird behavior but I managed to find a way to bypass it.

game.Players.PlayerAdded:Connect(function(Player)
    Player.ChildAdded:Connect(function(I)
        if I.Name == "Backpack" then
            I.ChildAdded:Connect(function()
                print("Hey")
            end)
        end
    end)
end)
Ad
Log in to vote
1
Answered by 5 years ago
Edited 5 years ago

karlo_tr10's code will work, but I think you should know why it works, so that you're not left with this mystery workaround you don't understand. Whenever adding a wait() mysteriously fixes something, you should dig into why, to make sure you haven't just added a race condition or subtle new bug.

What's actually going on here is that on the server, the Player object is initialized already having a Backpack as a child, before PlayerAdded is even fired. Your WaitForChild("Backpack") is getting a valid reference to a Backpack--one that is destroyed and replaced on the next server tick with a new Backpack, which is the one you actually want a reference to (and the one karlo's code gets a reference to).

This is tricky because WaitForChild() doesn't actually wait for a new child to be added, if there is a matching-named child already present, which in this case there is. So in your original code, you have a ChildAdded listener getting attached to something that exists only fleetingly, and isn't the Backpack that ever has anything put into it.

Full proof of this:

local Players = game:GetService("Players")

local function OnPlayerAdded(player)
    local backpack = player:WaitForChild("Backpack")
    print("backpack:",backpack)

    backpack.ChildAdded:Connect(function()
        print('Some Thing was added to the first backpack')
    end)

    player.ChildAdded:Connect(function(child)
        print("Player",player.Name," now has a child",child.Name,"of type",typeof(child))
        if child:IsA("Backpack") then

            print("Backpack added to",player.Name," is the same backpack we got from WaitForChild:",child == backpack)

            child.ChildAdded:Connect(function()
                print('Some Thing was added to the real backpack')
            end)
        end
    end)
end

Players.PlayerAdded:Connect(OnPlayerAdded)
for _,player in pairs(Players:GetPlayers()) do
    OnPlayerAdded(player)
end

Answer this question