Character Randomizer

Hey, developers! Recently, I’ve been trying to make a character randomizer which randomizes a character in StarterPlayer but it’s not randomizing.

I have the characters set up as shown in this picture below:
image

The script that’s supposed to assign a player a character from that selection is placed in StarterCharacterScripts and looks like this:

local characters = {}

for _, child in ipairs(game.StarterPlayer:GetChildren()) do
	if child:IsA("Model") and child.Name == "StarterCharacter" then
		table.insert(characters, child)
	end
end

if #characters > 0 then
	local function randomCharacter()
		return characters[math.random(1, #characters)]
	end

	local player = game.Players.LocalPlayer

	player.CharacterAdded:Wait()

	player.CharacterAdded:Connect(function(newCharacter)
		newCharacter = randomCharacter()
		player.Character = newCharacter
	end)
else
	print("There are no starter characters in StarterPlayer.")
end

The print statement at the end isn’t printing anything either.

I’ve tried moving the characters into replicated storage in a folder, but it’s still not working. If you have ideas on how to fix this please, let me know!

1 Like

You could try putting it in StarterPlayerScripts.

1 Like

I’ve tried it and it still doesn’t work :grimacing:

Welp, a few problems I’d guess. First, In order for a player’s character to change, it has to be done by the server in a server script. Second, since the starter characters aren’t grouped together, Roblox will automatically give the player the first one it finds. So with those two problems, that’s probably why it’s not randomizing. I’d recommend putting the code in a script in ServerScriptService and putting all the starter characters in a folder in ServerStorage. I revised the code a little so it uses Random.new() ensuring it’ll be a random integer.

-- In a script in ServerScriptService

local characters = game.ServerStorage:WaitForChild("StarterCharacters"):GetChildren() -- replace with where the folder is and the name of the folder

game.Players.PlayerAdded:Connect(function(player)
	if #characters > 0 then
		local starterChars = {}
		
		for i, char in ipairs(characters) do
			table.insert(starterChars, char)
		end
		
		local function randomCharacter()
			local random = Random.new()
			return starterChars[random:NextInteger(1, #characters)]
		end
		
		local newChar = randomCharacter():Clone()		
		
		player.CharacterAdded:Connect(function(oldChar)	
			local oldCFrame = oldChar:GetPrimaryPartCFrame()
			
			player.Character = newChar
			newChar.Parent = workspace
			newChar:SetPrimaryPartCFrame(oldCFrame)
			oldChar:Destroy()
		end)
	else
		print("There are no starter characters in StarterPlayer.")
	end
end)

I’ve gotten this error

on this line of code
image

Does it have to do anything with the startercharacters?

I made a small change to the code. Instead of using .CharacterAdded:Connect(), I used .CharacterAdded:Wait(). See if that makes any change to the error. I tested it out and it works for me.

-- In a script in ServerScriptService

local characters = game.ServerStorage:WaitForChild("StarterCharacters"):GetChildren() -- replace with where the folder is and the name of the folder

game.Players.PlayerAdded:Connect(function(player)
	if #characters > 0 then
		local starterChars = {}

		for i, char in ipairs(characters) do
			table.insert(starterChars, char)
		end

		local function randomCharacter()
			local random = Random.new()
			return starterChars[random:NextInteger(1, #characters)]
		end

		local newChar = randomCharacter():Clone()	
		local oldChar = player.Character or player.CharacterAdded:Wait()

		
		local oldCFrame = oldChar:GetPrimaryPartCFrame()
		
		player.Character = newChar
		newChar.Parent = workspace
		newChar:SetPrimaryPartCFrame(oldCFrame)
		oldChar:Destroy()
	else
		print("There are no starter characters in StarterPlayer.")
	end
end)

I’m basing my code off of another dev forum post on setting a player’s character.

Can you also show me where the characters are located in the explorer?

The characters are located here:
image

Okay, just make sure that the characters variable is = to game.ServerStorage.Characters

So it would be local characters = game.ServerStorage.Characters("Characters"):GetChildren()

characters = game.ServerStorage:WaitForChild("Characters"):GetChildren()

it still says the parent property is locked on line 24

Did you replace it with the second script? It shouldn’t be erroring unless there’s something else causing it to error.

Have Multiple HumanoidDescriptions in a Folder, pick a HumanoidDescription at random, then Apply that Description to the StarterCharacters Humanoid, from there it should apply all Clothing Accessories, Animations, and BodyColors to the Character.

Should not be too difficult, and should only take 3 lines at most to write:

local Descriptions = Example:GetChildren() -- Gets All Children in the Object
local NewDesc = Descriptions[math.random(#Descriptions)] -- Picks a Random Object based on the Number of items inside

Character.Humanoid:ApplyDescription(NewDesc) -- Applies Random Description

You should also change :GetPrimaryPartCFrame()/:SetPrimaryPartCFrame() with :GetPivot()/:PivotTo(), as those functions are deprecated.

As far as I’m aware, you cannot change a player character in a LocalScript. Maybe try doing this in a ServerScript, and potentially make use of the .PlayerAdded event (or whatever event you are currently using to fire this function) to change the player character.

Would this be what you’re trying to achieve?

local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")

local characters = ServerStorage:WaitForChild("Characters"):GetChildren()

local function getRandomCharacter(player)
	if #characters == 0 then
		warn("There are no available characters. Loading default character.")
		player:LoadCharacter()
	else
		local newCharacter = characters[math.random(1, #characters)]:Clone()
		player.Character = newCharacter
		newCharacter.Parent = workspace
	end
end

Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(character)
		local humanoid = character:WaitForChild("Humanoid")
		humanoid.Died:Connect(function()
			task.wait(Players.RespawnTime)
			getRandomCharacter(player)
		end)
	end)
	getRandomCharacter(player)
end)

The script is stored in ServerScriptService, and the character folder is stored in ServerStorage. I also turned off CharacterAutoLoads as it was causing the player to incorrectly load with it on.

Whoops, that’s my mistake. I tried the second script and it works! Thank you so much!

1 Like

I have just one more question, is it possible to assign a new character to a player when they die/reset?

Yeah it’s possible. I just edited the script a little so it works whenever the player dies. Each time the player respawns, they’ll spawn with a new random character. The only change I made in the explorer was disabling the CharacterAutoLoads property of Players. Replace the old script with this script and disable CharacterAutoLoads and it should work fine.

-- In a script in ServerScriptService

local characters = game.ServerStorage:WaitForChild("StarterCharacters"):GetChildren() -- replace with where the folder is and the name of the folder

game.Players.PlayerAdded:Connect(function(player)
	if #characters > 0 then
		local function assignCharacter()

			local starterChars = {}

			for i, char in ipairs(characters) do
				table.insert(starterChars, char)
			end

			local function randomCharacter()
				local random = Random.new()
				return starterChars[random:NextInteger(1, #characters)]
			end

			local newChar = randomCharacter():Clone()	

			player.Character = newChar
			newChar.Parent = workspace
		end
		
		player.CharacterAdded:Connect(function(c)
			local h = c:WaitForChild("Humanoid")
			h.Died:Connect(function()
				task.wait(3)
				assignCharacter()
			end)
		end)
		
		assignCharacter()
	else
		print("There are no starter characters in StarterPlayer.")
		player:LoadCharacter()
	end
end)