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

What is possibly wrong with my _G.GetPlayers() global function?

Asked by
IcyEvil 260 Moderation Voter
8 years ago
Edited 8 years ago

I receive no errors when it executes, but it simply just doesn't work.

I honestly have no clue what is wrong with it.

function _G.GetPlayer()
    local tppoints = game.Workspace["map tp"]:GetChildren()
    local randomSelect = math.random(1,#tppoints)
    local randomTp = tppoints[randomSelect]
    local players = game.Players:GetChildren()
for _,ply in pairs(players) do
    v = ply.Character
    local torso = ply:findFirstChild("Torso")
    for _,c in pairs(randomTp) do
        torso.CFrame = CFrame.new(c.Position)
    end
end
end



-- error

ServerScriptService.GetPlayers Global Function:9: bad argument #1 to 'pairs' (table expected, got Object)

I edited so that the script would update

-- original script
function _G.GetPlayer()
    local tppoints = game.Workspace["map tp"]:GetChildren()
    local randomSelect = math.random(1,#tppoints)
    local randomTp = tppoints[randomSelect]
    local players = game.Players()
    for _,v in pairs(players) do
    v = players.Character do
    local torso = v:findFirstChild("Torso")
    for _,c in pairs(randomTp) do
        torso.CFrame = CFrame.new(c.Position)
    end
end
    end
    end

2 answers

Log in to vote
2
Answered by
BlueTaslem 18071 Moderation Voter Administrator Community Moderator Super Administrator
8 years ago

First: Indent and space your code properly!

Addressing some problems:

game.Players() is not a function. To get all of the players, use game.Players:GetPlayers().

Use :FindFirstChild not :findFirstChild (it's deprecated).

Use workspace instead of game.Workspace.

Get rid of that useless do ... end in there, too.

You really shouldn't be changing v, and you should use better names. v and c are bad names, I don't know what a "v" is.

function _G.GetPlayer()
    local tppoints = workspace["map tp"]:GetChildren()
    local randomSelect = math.random(1, #tppoints)
    local randomTp = tppoints[randomSelect]
    local players = game.Players:GetPlayers()
    for _, player in pairs(players) do
        local character = players.Character
        local torso = character:FindFirstChild("Torso")
        for _, c in pairs(randomTp) do
            torso.CFrame = CFrame.new(c.Position)
        end
    end
end

Let's go over the types of the variables you have.

What i mean by "type" is what you are allowed to do with an object.

For example, a Player object has a .Character, which has a .Humanoid, which has a .Health. But a Player itself doesn't have a .Health; it's a different type of thing.

Similarly, workspace is an object; I can use :GetChildren() on it. The result of workspace:GetChildren() is a list of objects. I can use list[1] or #list or pairs(list), and these things give me different objects.

Let's write the types of all of the objects in your script.

function _G.GetPlayer()
    local tppoints = workspace["map tp"]:GetChildren()
    -- tppoints IS A list of parts
    local randomSelect = math.random(1,#tppoints)
    -- randomSelect IS A integer
    local randomTp = tppoints[randomSelect]
    -- randomTp IS A part
    local players = game.Players:GetPlayers()
    -- players IS A list of Players
    for _, player in pairs(players) do
        -- player IS A player
        local character = players.Character --> PROBLEM!
        -- character IS A character model
        local torso = character:FindFirstChild("Torso")
        for _, c in pairs(randomTp) do --> PROBLEM!
            torso.CFrame = CFrame.new(c.Position)
        end
    end
end

There are two problems here.

  1. You use players.Character, but players is a list, not a player. You mean to use player.Character
  2. You use pairs(randomTp), but randomTp isn't a list, it's a brick.

I'll simplify your code to just use randomTp instead where you had c to solve (2).

function _G.GetPlayer()
    local tppoints = workspace["map tp"]:GetChildren()
    local randomSelect = math.random(1,#tppoints)
    local randomTp = tppoints[randomSelect]
    local players = game.Players:GetPlayers()
    for _, player in pairs(players) do
        local character = player.Character 
        local torso = character:FindFirstChild("Torso")
        torso.CFrame = CFrame.new(randomTp.Position)
    end
end

There's a small problem here. torso can be nil (since it's the result of FindFirstChild), but you try modifying it.

Since it's possible the torso isn't there, you need to check for that case

        local torso = character:FindFirstChild("Torso")
        if torso then
            torso.CFrame = CFrame.new(randomTp.Position)
        end

In fact, you should also have a check that character isn't nil.

This script probably doesn't do what you want, though. It does this:

  • Pick a random spawn, randomTp
  • Teleport each player to that one randomTp spawn.

You probably want the random choice to be done for each player. But right now, it's not done inside the for loop, so it's not done for each.

Clean Code

Clean code reads like well-written prose.

Each part is very compact, understandable, and says exactly what you do.

Notice how the description / purpose of what the function does reads almost exactly like the code inside it?

-- find the torso (from the player's character) if it exists
-- set its CFrame to the target
function teleport(player, target)
    local character = player.Character
    if character then
        local torso = character:FindFirstChild("Torso")
        if torso then
            torso.CFrame = CFrame.new(target.Position)
        end
    end
end

-- choose the thing at a random position from 1 .. #list
-- inside list
function chooseRandomElement(list)
    return list[math.random(#list)]
end

-- choose a random spawn from the list of spawns in `workspace["map tp"]`
function randomSpawn()
    return chooseRandomElement(
        workspace["map tp"]:GetChildren()
    )
end

-- for each player in the game,
-- teleport that player to a random spawn
function teleportPlayers()
    for _, player in pairs(game.Players:GetPlayers()) do
        teleport(player, randomSpawn())
    end
end
0
Thank you so very much, very informative, and I will try to keep my code clean! IcyEvil 260 — 8y
0
Unfortunately it still does not work, but im going to accept your post as the answer considering Its as close to the answer as I am going to get I believe. IcyEvil 260 — 8y
Ad
Log in to vote
2
Answered by 8 years ago
Edited 8 years ago
for _,v in pairs(players.Character) do

It's this line. "players" is nothing but a table of all the players. It does not have a "Character" property, so you are essentially running pairs on nil.

Instead, do this:

for _,ply in pairs(players) do
    v = ply.Character
0
When i do this i receive; 22:27:16.040 - ServerScriptService.GetPlayers Global Function:5: attempt to call field 'Players' (a userdata value) IcyEvil 260 — 8y
0
change 'players' to 'plrs'. The script thinks 'players' == 'Players' User#9949 0 — 8y
0
I fixed the first error, but now a new one is up ' ServerScriptService.GetPlayers Global Function:9: bad argument #1 to 'pairs' (table expected, got Object) ' IcyEvil 260 — 8y

Answer this question