Script to change character's appearance on spawn not working

I am very new to scripting in general, and i’ve been trying to make a modulescript, CharacterCustomization, that holds race data for a bunch of races, which for now will simply be clothing and skin color.

This modulescript will be required by a script in serverscriptservice, which will apply a race to all players once they spawn. The modulescript is as follows:

local CharacterCustomization = {}

local raceData = {
	Human = {
		SkinColor = BrickColor.new("Beige"),
		Shirt = "rbxassetid://73557102", -- Replace with actual asset IDs
		Pants = "rbxassetid://73557125"
	},
	Aetherian = {
		SkinColor = BrickColor.new("Bright blue"),
		Shirt = "rbxassetid://2450222519",
		Pants = "rbxassetid://2450196657"
	},
	Solari = {
		SkinColor = BrickColor.new("Bright orange"),
		Shirt = "rbxassetid://31107254",
		Pants = "rbxassetid://635773681"
	}
}

function CharacterCustomization.SetCharacterAppearance(character, race)
	local data = raceData[race]

	if data then
		-- Wait for the Humanoid
		local humanoid = character:WaitForChild("Humanoid")
		local bodyColors = Instance.new("BodyColors", character)

		-- Debugging output
		print("Setting appearance for race: " .. race)


		bodyColors.HeadColor = data.SkinColor
		bodyColors.TorsoColor = data.SkinColor
		bodyColors.LeftArmColor = data.SkinColor
		bodyColors.RightArmColor = data.SkinColor
		bodyColors.LeftLegColor = data.SkinColor
		bodyColors.RightLegColor = data.SkinColor


		for _, item in pairs(character:GetChildren()) do
			if item:IsA("Shirt") or item:IsA("Pants") then
				print("Removing clothing: " .. item.Name)
				item:Destroy()
			end
		end

		local shirt = Instance.new("Shirt", character)
		shirt.ShirtTemplate = data.Shirt
		print("Applied new shirt: " .. data.Shirt)

		local pants = Instance.new("Pants", character)
		pants.PantsTemplate = data.Pants
		print("Applied new pants: " .. data.Pants)

	else
		warn("Race not found: " .. tostring(race))
	end
end

return CharacterCustomization

The serverscript, RaceHandler, is as follows:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local CharacterCustomization = require(ReplicatedStorage:WaitForChild("CharacterCustomization"))

-- List of available races
local races = {"Human", "Aetherian", "Solari"}

-- Function to get a random race
local function getRandomRace()
	return races[math.random(1, #races)]
end

game.Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(character)
		-- Wait for Humanoid to ensure it's loaded
		character:WaitForChild("Humanoid")

		-- Get a random race
		local playerRace = getRandomRace()

		-- Set character appearance based on the chosen race
		CharacterCustomization.SetCharacterAppearance(character, playerRace)
	end)
end)

(Please forgive the wonky patchup by ChatGPT, as i’ve tried to fix it using AI to no avail)

Whenever i have a player spawn, their clothing simply becomes invisible, and their skin color doesn’t change. Furthermore, explorer shows both the original clothing and new clothing, even though i’ve tried to delete them.

What errors am i making in these pieces of code? Thanks in advance.

From looking at your code, it looks like it should work. One suggestion I have though (which I’m not sure if it would make it work), would be to try just setting the shirt/pants template rather than deleting and recreating them. So instead of this:

try this:

	local shirt = character:FindFirstChildOfClass("Shirt") or Instance.new("Shirt", character)
	shirt.ShirtTemplate = data.Shirt
	print("Applied new shirt: " .. data.Shirt)

	local pants = character:FindFirstChildOfClass("Pants") or Instance.new("Pants", character)
	pants.PantsTemplate = data.Pants
	print("Applied new pants: " .. data.Pants)

I’m sorry, but this doesn’t work. Skin color remains unchanged, and the character still has no clothing. However, inside explorer it shows that the character has 2 shirts (one labeled clothing and the other labeled shirt) and 2 pants (same labels, but with pants)

Use HumanoidDescriptions, it will make your life so much easier, and is the way Roblox wants you to edit characters in game nowadays (since every Humanoid has one builtin, that you can get with Character.Humanoid:GetAppliedDescription)

HumanoidDescriptions like @metatablecat suggested is probably the way to go. When I used HumanoidDescriptions though, I had to work around it a bit. Since you’re doing it on spawn, make sure Players.CharacterAutoLoads = false.

Here is a sample of my code:

Players.CharacterAutoLoads = false
local function OnPlayerJoined(client: Player)
	local humanoidDescription = Players:GetHumanoidDescriptionFromUserId(client.UserId)
	humanoidDescription.Shirt = YOUR_ID_HERE
	humanoidDescription.PANTS = YOUR_ID_HERE
      

	client.CharacterAdded:Connect(function(character)
		local humanoid: Humanoid = character:WaitForChild("Humanoid")
		humanoid:ApplyDescription(humanoidDescription)

		humanoid.Died:Connect(function()
			task.wait(3)
			client:LoadCharacter()
			print("Respawning " .. client.Name .. "'s character")
		end)
	end)

	client:LoadCharacterWithHumanoidDescription(humanoidDescription)
end

image

Top ones are the ones that should be set by the script, but if i manually delete the bottom ones there still is no clothing.

I’m sorry, i’m still new and im not sure how to implement this.

For your usecase:

local desc = Humanoid:GetAppliedDescription()
desc.Shirt = SHIRT_ID_HERE
desc.Pants = PANTS_ID_HERE
Humanoid:ApplyDescription(desc)

If this doesn’t work, try cloning the description, i’m pretty sure they’ve fixed that though.
they fixed it, you dont need to clone the description to reapply it

wait let me patch that into your actual code

if data then
		-- Wait for the Humanoid
		local humanoid = character:WaitForChild("Humanoid")
		local desc = humanoid:GetAppliedDescription()
		
		desc.HeadColor = data.SkinColor
		desc.TorsoColor = data.SkinColor
		desc.LeftArmColor = data.SkinColor
		desc.RightArmColor = data.SkinColor
		desc.LeftLegColor = data.SkinColor
		desc.RightLegColor = data.SkinColor

		desc.Shirt = data.Shirt
		data.Pants = data.Pants

		humanoid:ApplyDescription(desc)
	else

Thank you! I implemented this and i didn’t work at first so i added a wait(2) before applying the description and it works perfectly! You’re a lifesaver

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.