Currently, I have a round system, and every round the player will have a custom character which is stored in a folder in ServerStorage and then cloned into Workspace. What would I have to do, to give a different character to every player?
for i,v in pairs (game.Players:GetPlayers()) do
Character = Characters[math.random(1, #Characters)]:Clone()
v.Character = Character
Character.Parent = game.Workspace
Changing the player’s character has always been a problem with no not-hacky way to do it. First thing is, you need to change their character from the client, and not the server, by :Destroy()ing the already existing one, and replacing it with the randomly chosen one. This also leans that the characters have to be stored in the client, so again, very security unfriendly.
local characters = game:GetService("ServerStorage").Characters:GetChildren()
Then you can iterate over all the players and give them a random character, and each time removing the chosen character from the table :
for i,player in pairs(game:GetService("Players"):GetPlayers()) do
local chosenCharacter = characters[math.random(1,#characters)]
-- set the players character to "chosenCharacter"
table.remove(characters,i) -- remove the chosenCharacter from the table
The only issue this method would spark however, is if you have more players than there
are characters in your folder. To detect this :
if #characters == 0 then
-- uh oh! no more characters to give out to the players!
Usually one of the best ways to do this is to shuffle a table of all options and then sequentially use them.
There are a few ways to go about shuffling a table, and I suggest you look for other threads or online forums for how to create table shuffling functions as that question has been answered plenty of times on the web before, haha.
Anyways the basic idea is this:
Use :GetChildren() to get a table of all options.
Run your loop using the sequential indexes of the now shuffled table.
Return to step 2 to get randomize again.
-- Initialize list of characters.
local charList = game.Path.To.Characters:GetChildren()
shuffle(charList) -- Remember you need to make a table shuffling function.
for i,v in pairs(game.Players:GetPlayers())
local char = charList[i]:Clone()
v.Character = char
char.Parent = game.Workspace
Now you’ll still want to make sure you do things like check there are more characters than players, etc. This is just the basic concept.
You could create a Server (Not client) script located in ServerScriptService that calls Humanoid:ApplyDescription from a loop within that same server script. So what you’ve done shows the right idea, but instead of cloning anything.
What I’d recommend you do is: for each random character model you’d like, you could create (there are various ways to do this such as using the avatar editor and then copying your character and pasting it in studio) the character itself, and then get the HumanoidDescription of that character.
(Change your models to Humanoid Descriptions that would give the desired look of your characters)
Once the Humanoid Description’s properties resemble that of your character, you can just place the HumanoidDescription into your folders and still give them names. (Like 1,2,3, or anything)
Once you’ve set up your 3 descriptions in your folder like this, you could instead call on the server:
If your game has an intermission for example, once the server has detected that it’s over, you can make a remote event that would fire the following function but this is the core code for whatever you would use:)
`for i,v in pairs (game.Players:GetPlayers()) do
local Character = Player.Character
local Humanoid = Character:FindFirstChildOfClass("Humanoid")
local NewCharacter = Humanoid:ApplyDescription(characters[math.random(1,#characters)])
I believe this is more secure (not sure if performance efficient) in the way that the server wouldn’t see an exploiter’s character changes if they did make any. Other players would only see your characters as the descriptions were applied on the server.