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)
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
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
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.
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.
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?
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()