Two problems with character creation system

Hello devs, i’m here looking for help with some issues with HumanoidDescriptions and remote events.
This is going to be quite alot, so make sure you have a good level of patience.

LocalScript (note some lines were removed due to being irrelevant):

-- SORT PLAYER STUFF --
if Player.PlayerGui.CharacterCreationScreen.Enabled == true then
	IsOnCCS = true
	HidePlayers("DoHide")
	print("players hidden")
	print("is on ccs")
	--
	charchildaddedconnection = PlayerCharacter.ChildAdded:Connect(CharChildAdded)
	SortCharacterModelEvent:FireServer(Player)
	wait(5)
	game:GetService("TweenService"):Create(Background,TweenInfo.new(5,Enum.EasingStyle.Linear,Enum.EasingDirection.In),{BackgroundTransparency = 1 }):Play()
	if IsOnCCS == true then
		game:GetService("RunService").RenderStepped:Connect(function()
			Camera.CFrame = CameraPosition.CFrame
		end)	
	end
	PlayerCharacter.PrimaryPart.CFrame = CFrame.new(CharacterSpawn.Position + Vector3.new(0,3,0))
	PlayerCharacter.PrimaryPart.CFrame = CFrame.lookAt(PlayerCharacter.PrimaryPart.Position, Vector3.new(744.4, 5.607, 366.559))
end
------------------------

HairButton.MouseButton1Up:Connect(function()
	if ButtonDebounce == false then
		ButtonDebounce = true
		spawn(function()
			wait(1)
			ButtonDebounce = false
		end)
	HairSelectNumber += 1
	if HairSelectNumber > HairEntries then
		HairSelectNumber = 1
	end
		CreateCharacterEvent:FireServer("HairAccessory",Hair[HairSelectNumber],PlayerHumanoidDescription,PlayerHumanoid)
		end
end)

--[[HairColorButton.MouseButton1Up:Connect(function()
	HairColorsSelectNumber += 1
	if HairColorsSelectNumber > HairColorsEntries then
		HairColorsSelectNumber = 1
	end
	HairColorEvent:FireServer(Hair[HairSelectNumber],HairColors[HairColorsSelectNumber])
end)--]]

SkinColorButton.MouseButton1Up:Connect(function()
	if ButtonDebounce == false then
		ButtonDebounce = true
		spawn(function()
			wait(1)
			ButtonDebounce = false
		end)
	SkinColorSelectNumber += 1
	if SkinColorSelectNumber > SkinColorsEntries then
		SkinColorSelectNumber = 1
	end
	CreateCharacterEvent:FireServer("LeftLegColor",SkinColors[SkinColorSelectNumber],PlayerHumanoidDescription,PlayerHumanoid)
		wait(0.050)
		CreateCharacterEvent:FireServer("LeftArmColor",SkinColors[SkinColorSelectNumber],PlayerHumanoidDescription,PlayerHumanoid)
		wait(0.050)
		CreateCharacterEvent:FireServer("RightLegColor",SkinColors[SkinColorSelectNumber],PlayerHumanoidDescription,PlayerHumanoid)
		wait(0.050)
		CreateCharacterEvent:FireServer("TorsoColor",SkinColors[SkinColorSelectNumber],PlayerHumanoidDescription,PlayerHumanoid)
		wait(0.050)
		CreateCharacterEvent:FireServer("RightArmColor",SkinColors[SkinColorSelectNumber],PlayerHumanoidDescription,PlayerHumanoid)
		wait(0.050)
		CreateCharacterEvent:FireServer("HeadColor",SkinColors[SkinColorSelectNumber],PlayerHumanoidDescription,PlayerHumanoid)
	end
end)

TrousersButton.MouseButton1Up:Connect(function()
	if ButtonDebounce == false then
		ButtonDebounce = true
		spawn(function()
			wait(1)
			ButtonDebounce = false
		end)
		PantsSelectNumber += 1
		if PantsSelectNumber > PantsEntries then
			PantsSelectNumber = 1
		end
		CreateCharacterEvent:FireServer("Pants",Pants[PantsSelectNumber],PlayerHumanoidDescription,PlayerHumanoid)
	end
end)

ShirtButton.MouseButton1Up:Connect(function()
	if ButtonDebounce == false then
		ButtonDebounce = true
		spawn(function()
			wait(1)
			ButtonDebounce = false
		end)
		if UpperClothingSelectNumber > UpperClothingEntries then
			UpperClothingSelectNumber = 1
		end
		CreateCharacterEvent:FireServer("Shirt",UpperClothing[UpperClothingSelectNumber],PlayerHumanoidDescription,PlayerHumanoid)
	end
end)

FaceButton.MouseButton1Up:Connect(function()
	if ButtonDebounce == false then
		ButtonDebounce = true
		spawn(function()
			wait(1)
			ButtonDebounce = false
		end)
		if FacesSelectionNumber > FacesEntries then
			FacesSelectionNumber = 1
		end
		CreateCharacterEvent:FireServer("Face",FaceS[FacesSelectionNumber],PlayerHumanoidDescription,PlayerHumanoid)
	end
end)

I grabbed the biggest blocks of code to display, but if inconvenience arises i will show the full block.

Here are the variables used throughout (emphasis so not easily overlooked):

ButtonDebounce = A debounce variable used to stop players spamming and breaking the system.

HairButton = A TextButton that changes players’ hair when pressed.

SkinColorButton = Same as TextButton, changing skin color when pressed.

The buttons (hairbutton,upperclothing etc.) = a number used to navigate the Hair and SkinColors table. It is created by a local function i have made (which you can see here)

TableEntryNumberGatherer
local function TableEntryNumberGatherer(tabletosearch)
	local entrycount = 0
	for i, entry in pairs(tabletosearch) do
		entrycount += 1
	end
	return entrycount
 end

charchildconnection & CharChildAdded = Used to combat the player’s HumanoidDescription from reading as nil upon the ServerScript making a new one (see ServerScript)

The variable and function
local charchildaddedconnection
local function CharChildAdded(child)
	if IsOnCCS == true then
		print("child added")
		if child:IsA("HumanoidDescription") then
			print(typeof(child))
			PlayerHumanoidDescription = child
			charchildaddedconnection:Disconnect()
			end
	else return end
end

Hair/SkinColors/UpperClothing etc. = Tables containing Color3 values and accessory and clothing id’s to be used.

local SkinColors = {
	
	 Color3.new(159, 122, 95),
	 Color3.new(99, 75, 59),
	 Color3.new(56, 41, 32),
	
   Color3.new(240, 184, 135),
	 Color3.new(227, 207, 165),
	
   Color3.new(226, 163, 90),
	 Color3.new(226, 136, 71),
	 Color3.new(170, 103, 56)
	
}

local SkinColorSelectNumber =  0
local SkinColorsEntries = TableEntryNumberGatherer(SkinColors)

local UpperClothing = {
	
	 "6431292082",
	 "6431294104",
	 "5822945874",
	 "4663573318",
	 "7257676380",
	
	 "2217975288",
	 "6458425936",
	 "6910039367",
	 "347825781",
	 "6431289497"
	
}

local UpperClothingSelectNumber = 0
local UpperClothingEntries = TableEntryNumberGatherer(UpperClothing)

local Pants = {
	
	"4461022686",
	"5941884235",
	"1876931299",
	"6458428133",
	"215120727"
	
}

local PantsSelectNumber = 0
local PantsEntries = TableEntryNumberGatherer(Pants)

local Hair = {
	
	"16630147",
	"2956239660",
	"376524487",
	"3814474927",
	"63690008",
	"376548738",
	"376526888",
	"376527350",
	"417457139",
	"1708329071",
	"3814456274",
	"1772372988",
	"3814496544",
	"3814450142"
	
}

local HairColors = {
	
	Color3.new(0,0,0),
	Color3.new(0.568627, 0.568627, 0.568627),
	Color3.new(0.988235, 0.823529, 0.321569),
	Color3.new(1, 0.627451, 0.2)
	
}

local HairSelectNumber = 0
local HairColorsSelectNumber = 0
local HairColorsEntries = TableEntryNumberGatherer(HairColors)
local HairEntries = TableEntryNumberGatherer(Hair)

local FaceS = {
	
	"rbxasset://textures/face.png",
	"7074764",
	"7699174",
	"7075502",
	"7074786",
	"12145366",
	"31117267",
	"7075469"
	
}

local FacesSelectionNumber = 0
local FacesEntries = TableEntryNumberGatherer(FaceS)

CreateCharacterEvent = A remote event used to communicate between the client and the server, to also send the ID’s over.

PlayerHumanoidDescription & PlayerHumanoid = Player’s HumanoidDescription and Humanoid.

Server Script:

local RemoteEventsFolder = game.ReplicatedStorage:WaitForChild("RemoteEvents")

local SortCharacterModelEvent = RemoteEventsFolder:WaitForChild("SortCharacterModel")
local CreateCharacterEvent = RemoteEventsFolder:WaitForChild("CreateCharacter")
local HairColorEvent = RemoteEventsFolder:WaitForChild("HairColor")

local CharacterCreationFolder = workspace:WaitForChild("CharacterCreation")
local CharacterCreationRoom = CharacterCreationFolder:WaitForChild("CharacterCreationRoom")

local CharacterSpawnCCR = CharacterCreationRoom:WaitForChild("CharacterSpawn")

---- EVENT FUNCTIONS ----

SortCharacterModelEvent.OnServerEvent:Connect(function(Player)
	print("sorting")
	local PlayerCharacter = Player.Character
	local PlayerCharacterParts = PlayerCharacter:FindFirstChildOfClass("Part")
	local PlayerHumanoid = PlayerCharacter:FindFirstChildOfClass("Humanoid")
	PlayerHumanoid.UseJumpPower = true
	PlayerHumanoid.WalkSpeed = 0
	PlayerHumanoid.JumpPower = 0
	PlayerCharacterParts.Anchored = true
	PlayerCharacterParts.Anchored = false
	PlayerHumanoid:RemoveAccessories()
	local HumanoidDescription = PlayerHumanoid:FindFirstChildOfClass("HumanoidDescription")
	--warn(HumanoidDescription)
	HumanoidDescription:Destroy()
	--warn(HumanoidDescription)
	local NewHumanoidDescription = Instance.new("HumanoidDescription")
	--warn(NewHumanoidDescription)
	NewHumanoidDescription.Parent = PlayerHumanoid
	
	NewHumanoidDescription.HeadColor = Color3.new(0.898039, 0.898039, 0.898039)
	NewHumanoidDescription.LeftArmColor = Color3.new(0.898039, 0.898039, 0.898039)
	NewHumanoidDescription.LeftLegColor = Color3.new(0.898039, 0.898039, 0.898039)
	NewHumanoidDescription.RightArmColor = Color3.new(0.898039, 0.898039, 0.898039)
	NewHumanoidDescription.RightLegColor = Color3.new(0.898039, 0.898039, 0.898039)
	NewHumanoidDescription.TorsoColor = Color3.new(0.898039, 0.898039, 0.898039)
	
	NewHumanoidDescription.Shirt = "7402745350"
	NewHumanoidDescription.Pants = "129458426"
	
	PlayerHumanoid:ApplyDescription(NewHumanoidDescription)
	print("applied")
	
	local PlayerFace = Player.Character.Head:WaitForChild("face")
	PlayerFace.Texture = "rbxasset://textures/face.png"
	
	for i, charpart in pairs(PlayerCharacter:GetChildren()) do
		if charpart:IsA("CharacterMesh") then
			charpart:Destroy()
		end
	end
end)

CreateCharacterEvent.OnServerEvent:Connect(function(player,hdstring,hdid,hd,hum) 
	print(typeof(player))
	print(typeof(hdstring))
	print(typeof(hdid))
	print(typeof(hd))
	print(typeof(hum))
	hd[hdstring] = hdid
	hum:ApplyDescription(hd)
end)

The variables in the CreateCharacter event are the same things sent by the LocalScript in the brackets, just with their names being shortened.

Now for the issues.

Firstly, in the SortCharacterModelEvent, when it creates the new description and applies it to the Player’s humanoid it doesn’t apply the clothing, but it applies the skin color.

An image to clarify:


(character creation UI was disabled to take this picture)

As you can see, i’ve put in the clothing ID’s properly and called ApplyDescription, so i’d appreciate it alot if somebody could tell me what’s going on.

Secondly, the buttons randomly work, and then they don’t work.

Primarily, it only works when i press the Trousers button, and then when i press anything else, it just breaks and errors:
devforumimage2
And by the looks of it, the HumanoidDescription randomly reads as nil, despite me looking into my character model and finding it still existing there.
A video to clarify here:
robloxapp-20211209-1424214.wmv (2.0 MB)
The error above occurs at the 21 second mark.

Somehow aswell, the ID’s start randomly reading as nil too, making the entire thing a slimy mess.

Again, i’d really appreciate if somebody could help me out with this, as this whole system has been nagging at me for a week now. If i miss anything, i’ll make an edit and add it to the post. Thank you in advance.

1 Like
NewHumanoidDescription.Parent = PlayerHumanoid

Try parenting it after the properties have been set.

1 Like

Fixed the problem on my own by using Player:ClearCharacterAppearance and using same player humanoid description, along with GetAppliedDescription for the CreateCharacterEvent. Thank you for your attention.