Teleporter not working?

I made it so when a round starts it teleports all players to a part, but it isn’t working. Here is the code.
Script.

--SpyxSpy main script
game.Players.PlayerAdded:Wait()

local SpyKit = game.ReplicatedStorage.Sword

local SoldierKit = game.ReplicatedStorage.Deagle

local remoteEvent = game.ReplicatedStorage:FindFirstChild("GUIEvent")

local timeEvent = game.ReplicatedStorage:FindFirstChild("timeEvent")

local RoundGuiText = game.StarterGui.RoundGui.Frame.TextLabel

local MinPlayers = script.MinPlayers

local MinPlayersValue = script.MinPlayers.Value

local spawns = {"Spawn1", "Spawn2", "Spawn3", "Spawn4", "Spawn5", "Spawn6"}

local selectedSpawn = spawns[math.random(1, #spawns)]

local Teleport = selectedSpawn

local spawn = workspace[selectedSpawn]

local IntermissionTime = 20

local timerTag = game.ReplicatedStorage:FindFirstChild("timerTag")

local RoundTime = 240

local players = game.Players:GetPlayers()

local roles = { --our roles table, where the name means the maximum members
    {Name = "Scientist", Max = 6},
    {Name = "Spy", Max = 1},
    {Name = "Soldier", Max = 2}
}
local playerRoles = {} --will store what players have what roles

function getRoleMembers(roleName) --returns a table of players that have a role
    local playerTable = {}
    for player,role in pairs(playerRoles) do
        if role == roleName then
            playerTable[#playerTable + 1] = player
        end
    end
    return playerTable
end

function getRolesFull() --checks if all the roles are full
    for _,roleTbl in pairs(roles) do
        if #getRoleMembers(roleTbl.Name) < roleTbl.Max then
            return false
        end
    end
    return true
end

function getRole() --get a random role name that isnt full
    if getRolesFull() then
        return nil
    end
    local chosen
    repeat
        chosen = roles[math.random(1,#roles)]
    until #getRoleMembers(chosen.Name) < chosen.Max
    return chosen.Name
end

for _,player in pairs(players) do --select each player's role
    local selectedRole = getRole()
	playerRoles[player] = selectedRole
	print(selectedRole)
	remoteEvent:FireClient(player,selectedRole)
end
target = (selectedSpawn)
while true do
    for i=10, 0, -1 do
          game:GetService("ReplicatedStorage").IntermissionTime.Value = i
        wait(1)
end
    for i=30, 0, -1 do
          game:GetService("ReplicatedStorage").RoundTime.Value = i
        wait(1)
    end
    wait()
end
while IntermissionTime.Value == 0 do
	for i, player in ipairs(game.Players:GetChildren()) do
   		if player.Character and player.Character:FindFirstChild("HumanoidRootPart") then
      		player.Character.HumanoidRootPart.CFrame = target
   end
end

local script

local Player = game.Players.LocalPlayer
local RoundText = script.Parent---LOCATION RELATIVE TO SCRIPT
local IntermissionTime = game.ReplicatedStorage.IntermissionTime
local RoundTime = game.ReplicatedStorage.RoundTime
IntermissionTime.Changed:Connect(function(newTime)
    RoundText.Text = newTime
end)
RoundTime.Changed:Connect(function(newTime2)
    RoundText.Text = newTime2
end)
2 Likes

Try using the torso instead of the HRP.(Not sure tbh)

2 Likes

Tried that, it breaks the text

Solved by DaCrazyDev. 30 chars.

It seems you have did a typo instead on in pairs, you did ipairs

1 Like

Oh, thanks. I fixed that and did

while IntermissionTime.Value == 0 do
	for i, player in ipairs(game.Players:GetChildren()) do
   		if player.Character and player.Character:FindFirstChild("HumanoidRootPart") then
      		player.Character.HumanoidRootPart:SetPrimaryPartCFrame(target)
   		end
	end
end

but it still doesn’t work, with no errors.

1 Like

The problem is that you’re setting the HumanoidRootPart’s CFrame to target which is a randomly selected Instance, and not the CFrame of that instance.

As target is an object, you can’t set the CFrame of a part to an object.

You need to do target.CFrame

Also, you should use pairs not ipairs in your for loop, as if one of the values is nil, it will break the entire loop.

Change the last part of your code to this:

while IntermissionTime.Value == 0 do
	for i, player in pairs(game.Players:GetChildren()) do
   		if player.Character and player.Character:FindFirstChild("HumanoidRootPart") then
      		player.Character.HumanoidRootPart.CFrame = target.CFrame 
        end
   end
end
2 Likes

That is not the issue, however, it’s not recommended to use ipairs for this type of iteration.

1 Like

I now have

while IntermissionTime.Value == 0 do
	for i, player in pairs(game.Players:GetChildren()) do
   		if player.Character and player.Character:FindFirstChild("HumanoidRootPart") then
      		player.Character.HumanoidRootPart.CFrame = target.CFrame 
        end
   end
end

I checked the values and the values are changing to 0, so the loop isn’t teleporting. I also tried putting a print statement to check if the loop works, but nothing was printed.

Ohh I see another issue.

while true do
    for i=10, 0, -1 do
          game:GetService("ReplicatedStorage").IntermissionTime.Value = i
        wait(1)
end
    for i=30, 0, -1 do
          game:GetService("ReplicatedStorage").RoundTime.Value = i
        wait(1)
    end
    wait()
end
while IntermissionTime.Value == 0 do
	for i, player in ipairs(game.Players:GetChildren()) do
   		if player.Character and player.Character:FindFirstChild("HumanoidRootPart") then
      		player.Character.HumanoidRootPart.CFrame = target
   end
end

Your first while loop uses while true do which is a continuous never ending loop.
Your second loop never actually starts.

Also, your variables IntermissionTime and RoundTime aren’t ObjectValue’s they don’t have a .Value`, however, I assume that you do have ObjectValues with the same names in ReplicatedStorage so the client can keep track of them too, which you got confused with.

Change the last part of your code (from line 77 to 93) to:

local IntermissionCount = coroutine.wrap(function()
  for i = 10, 0, -1 do 
    IntermissionTime = i 
    game:GetService("ReplicatdStorage").IntermissionTime.Value = i 
    wait(1)
  end 
 -- The code below will teleport the players to the target as soon as the count finishes
  for i, player in ipairs(game.Players:GetChildren()) do
    if player.Character and player.Character:FindFirstChild("HumanoidRootPart") then
      player.Character.HumanoidRootPart.CFrame = target.CFrame
    end 
  end
end)

local RoundCount = coroutine.wrap(function()
  for i = 30, 0, -1 do 
    RoundTime = i
    game:getService("ReplicatedStorage").RoundTime.Value = i  
    wait(1)
  end 
end)

IntermissionCount()
RoundCount() 

Using coroutines will allow you to change the IntermissionTime and the RoundTime at the same time, and after the IntermissionTime for loop is finished, it should teleport all the players. You don’t even need a while loop for this kind of thing.

Hopefully this helped.

1 Like

I’ve edited my new answer (30 chars)

1 Like

I got the error “20:47:24.502 - Workspace.Main:87: bad argument #3 (CFrame expected, got nil)”
and it skips the intermission countdown and goes straight to round time, also how do I loop this?

The problem with that is that you’re setting target to selectedSpawn
target = (selectedSpawn)

local spawns = {"Spawn1", "Spawn2", "Spawn3", "Spawn4", "Spawn5", "Spawn6"}

local selectedSpawn = spawns[math.random(1, #spawns)]

which means target is a string, and doesn’t have a CFrame

you need to use the selected object, which you have set here
local spawn = workspace[selectedSpawn]

The reason it skipped the intermission count is because of the error.

Change this (I believe it’s on line 76 or near that)
target = (selectedSpawn)
to
target = spawn

and I think it should work.

Also, you don’t need to loop it. For a round system, put this all into a function and call it everytime a game ends with some sort of event.

1 Like

Once it teleports players, it just stays at 0

What just stays at 0? (30 chars)

1 Like

The GUI just shows 0 with nothing else

and, it also teleports all the players to the same spawn

Hmm, maybe because I did the round timer and the intermission timer running on two coroutine threads when they’re supposed to be one after the other. Didn’t realize. Try this:

local function Start()
  for i = 10, 0, -1 do 
    IntermissionTime = i 
    game:GetService("ReplicatdStorage").IntermissionTime.Value = i 
    wait(1)
  end 
 -- The code below will teleport the players to the target as soon as the count finishes
  for i, player in ipairs(game.Players:GetChildren()) do
    if player.Character and player.Character:FindFirstChild("HumanoidRootPart") then
      player.Character.HumanoidRootPart.CFrame = target.CFrame
    end 
  end
  -- After all players are teleported, the round will start counting down 
  for i = 30, 0, -1 do 
    RoundTime = i
    game:getService("ReplicatedStorage").RoundTime.Value = i  
    wait(1)
  end 
end 

Start()
1 Like

Thanks, also when the players spawn they are constantly being moved forwards even when pressing buttons

That’s because you’re moving them all to target.CFrame…you said you wanted to teleport all players to a part.

If you want to set them each to a random part you need to change the target each time the loop iterates.

1 Like