I am currently trying to make a very simple system as part of a larger game, where after the intermission ends, 6 random players are teleported into 6 random seats.
I have 2 issues, currently, multiple players can be teleported to a single seat, and I am not sure how to loop it only six times (that way it only teleports 6 random players) while also being able to reference the select player instances so I can move their characters.
i’m sure there is a very simple fix to this, but I can’t seem to find it. Thanks!
local module = require(script.Parent.ModuleScript)
task.wait(5)
for i, v in game:GetService("Players"):GetChildren() do
local randomSeat = module.Seats[math.random(1, #module.Seats)]
v.Character:MoveTo(randomSeat.Position)
end
Since you’re randomly selecting both players and seats, I would write a generic function for choosing random instances from an array.
local function PickRandomItems(List, Amount)
List = table.clone(List) -- Create a shallow copy of the list so we can modify it without adverse effects
-- If the list doesn't have Amount items (say you wanted 6 players but only 2 are in the server) pick as many as possible
Amount = math.min(#List, Amount)
local PickedItems = {}
for Index = 1, Amount do
local RandomIndex = math.random(1, #List) -- Pick a random index corresponding to an item in the list
table.insert(PickedItems, List[RandomIndex]) -- Add the randomly selected item to the list
table.remove(List, RandomIndex) -- Remove the selected item from the original list so it can't be picked twice
end
return PickedItems
end
Then, whenever you need to put players in seats:
local Players = game:GetService("Players")
local ChosenPlayers = PickRandomItems(Players:GetPlayers(), 6) -- Pick 6 random players
local ChosenSeats = PickRandomItems(module.Seats, math.min(6, #ChosenPlayers)) -- Pick 6 random seats, or less if there aren't 6 players
for Index = 1, 6 do
local Player = ChosenPlayers[Index]
local Seat = ChosenSeats[Index]
-- Remember, there might not always be 6 players available, so we need to verify that Player exists before trying to put them in a seat
if Player then
Player.Character:MoveTo(Seat.Position)
end
end
You should clone the input array so as not to cause damaging changes. I doubt OP would like for module.Seats to run out of values before soon. I’d further verify that the number of seats returned does not fall below the number of players returned. You can also optimize the latter random sampling by passing the length of the “ChosenPlayers” array to your PickRandomItems call on module.Seats
Good catch, thanks. As for the possibility of there not being enough seats, I wrote this assuming the number of seats is a constant, but an if Seat could fix that issue if it arises.
There’s no need to through both arrays just to do nothing. It’s best to confirm your conditions before doing work. Also, since you’re writing a generalized function, you should clone the array internally. You should also make sure that the player’s character is available before attempting to move them. Finally, Model:MoveTo is not ideal due to its unavoidable and over-exaggerated anti-vertical collision feature. You’ll want to use PivotTo instead for better control. @ironoshea
local function getRandomValues<T>(array: {T}, amount: number): T
local clone = table.clone(array)
local values = {}
for _ = 1, math.min(#clone, amount) do
local value = table.remove(clone, math.random(#clone))
table.insert(values, value)
end
return values
end
local randomPlayers = getRandomValues(Players:GetPlayers(), 6)
local randomSeats = getRandomValues(seats, #randomPlayers)
if #randomSeats < #randomPlayers then
return
end
for index, player in randomPlayers do
local character = player.Character
if not character then
continue
end
local seat = randomSeats[index]
local cframe = CFrame.new(seat.Position)
character:PivotTo(cframe)
end
I agree, and I’ve already edited my function to clone the array internally, even though it is redundant for GetPlayers. Anyway, thanks for the feedback.
Awesome. I know it’s redundant, but that’s just how things go when we write generalized functions. After all, they’re not supposed to privy to what’s been done on the input prior to and after its arrival