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

Why does this PlayerAdded connect function script only work once?

Asked by 7 years ago
Edited 7 years ago

Really needing help on this lol, every time I use player added something gets messed up. The script only works when the player first joins and doesn't work if they reset! Can somebody fix this?

game.Players.PlayerAdded:connect(function(player)
    while not player.Character do wait() end
    local Ch=player.Character


local g = script.Arm2:clone()
        g.Parent = Ch
        local C = g:GetChildren()
        for i=1, #C do
            if C[i].className == "Part" then
                local W = Instance.new("Weld")
                W.Part0 = g.Middle
                W.Part1 = C[i]
                local CJ = CFrame.new(g.Middle.Position)
                local C0 = g.Middle.CFrame:inverse()*CJ
                local C1 = C[i].CFrame:inverse()*CJ
                W.C0 = C0
                W.C1 = C1
                W.Parent = g.Middle
            end
                local Y = Instance.new("Weld")
                Y.Part0 = Ch["Right Arm"]
                Y.Part1 = g.Middle
                Y.C0 = CFrame.new(0, 0, 0)
                Y.Parent = Y.Part0
        end

        local h = g:GetChildren()
        for i = 1, # h do
            if h[i].className == "Part" then
                h[i].Anchored = false
                h[i].CanCollide = false
            end
        end








end)

2 answers

Log in to vote
1
Answered by 7 years ago

I took the liberty of fixing your tabbing:

game.Players.PlayerAdded:connect(function(player)
    while not player.Character do
        wait()
    end

    local Ch = player.Character


    local g = script.Arm2:clone()
    g.Parent = Ch
    local C = g:GetChildren()

    for i=1, #C do

        if C[i].className == "Part" then
            local W = Instance.new("Weld")
            W.Part0 = g.Middle
            W.Part1 = C[i]
            local CJ = CFrame.new(g.Middle.Position)
            local C0 = g.Middle.CFrame:inverse()*CJ
            local C1 = C[i].CFrame:inverse()*CJ
            W.C0 = C0
            W.C1 = C1
            W.Parent = g.Middle
        end

        local Y = Instance.new("Weld")
        Y.Part0 = Ch["Right Arm"]
        Y.Part1 = g.Middle
        Y.C0 = CFrame.new(0, 0, 0)
        Y.Parent = Y.Part0

    end

    local h = g:GetChildren()
    for i = 1, # h do
        if h[i].className == "Part" then
            h[i].Anchored = false
            h[i].CanCollide = false
        end
    end
end)

Now, you'll see at the top of your script how you define the character.

As soon as the player joins, you wait for their character to load then you run the code. However, you only do this when they join.

The simple answer is to use the CharacterAdded event.

Here's an example:

game.Players.PlayerAdded:Connect(plr)
    plr.CharacterAdded:Connect(function(char)
        print(plr.Name.." 's character added!")
    end)
end)

That will print every time the player respawns.

Adding this to your code we get something like this:

game.Players.PlayerAdded:connect(function(player)
    player.CharacterAdded:Connect(function(Ch)

        local g = script.Arm2:clone()
        g.Parent = Ch
        local C = g:GetChildren()

        for i=1, #C do

            if C[i].className == "Part" then
                local W = Instance.new("Weld")
                W.Part0 = g.Middle
                W.Part1 = C[i]
                local CJ = CFrame.new(g.Middle.Position)
                local C0 = g.Middle.CFrame:inverse()*CJ
                local C1 = C[i].CFrame:inverse()*CJ
                W.C0 = C0
                W.C1 = C1
                W.Parent = g.Middle
            end

            local Y = Instance.new("Weld")
            Y.Part0 = Ch["Right Arm"]
            Y.Part1 = g.Middle
            Y.C0 = CFrame.new(0, 0, 0)
            Y.Parent = Y.Part0

        end

        local h = g:GetChildren()
        for i = 1, # h do
            if h[i].className == "Part" then
                h[i].Anchored = false
                h[i].CanCollide = false
            end
        end
    end)
end)
This is only an example.
0
Yeah but this doesn't fix his issue with the script only be called once. Take all that code and put it into a seperate function, called by the event. JasonTheOwner 391 — 7y
0
Why not use the Generic For instead of iterating like the above? Also, why use 'ClassName' to compare object types? Imo, that gets repetitive, b/c you're repeating typing that, while you can use 'IsA', which uses less typing, and all the flaws w/ the 'ClassName' comparison(ing) is very little to occur w/ it. TheeDeathCaster 2368 — 7y
0
King of helping me w all my errors, it actually works Thanks SM! greybird700 63 — 7y
0
This really helps because now I can fix the rest of my scripts that had the same error greybird700 63 — 7y
Ad
Log in to vote
0
Answered by 7 years ago
Edited 7 years ago

This is because you need to setup a player Died event.

Roblox has an example here

The code they use is:

game:GetService('Players').PlayerAdded:connect(function(player)
    player.CharacterAdded:connect(function(character)
        character:WaitForChild("Humanoid").Died:connect(function()
            print(player.Name .. " has died!")
        end)
    end)
end)

However, I would have a function called for starting the game, that gets called within the PlayerAdded event, and then where the example above has the print statment printing the player has died, call a function that resets the player.

I see you already have a ton of code written for when a player is added... take all of it, which another responder has helped in reformatting, and put it into a function that you can call when both a player is added and when a player is died. That should be the ULTIMATE solution.

Hope this helps.

-Jason

Answer this question