Saving Character Customisation

Hello! Recently I have started adding some ‘Character Customisation’ features into my game, but I’d like to save what the player has created. How would I achieve this?

My Customisation Script:

local selectionframe = script.Parent.SelectionFrame
local selectionframes = script.Parent.SelectionFrames
local ifviewing = script.Parent.IfViewing

local clone = game.Workspace:WaitForChild("".. game.Players.LocalPlayer.Name .. "'s_Clone")




--------------------------------------------------------------------------------------------------
--Hats
local Hats = selectionframes.HatSelectionFrame

Hats.Hat1.MouseButton1Click:Connect(function()
	if Hats.Hat1.IfWearing.Value == false then
		Hats.Hat1.IfWearing.Value = true
		if clone:FindFirstChild("Hat2") then
			clone.Hat2:Destroy()
		end
		if clone:FindFirstChild("Hat3") then
			clone.Hat3:Destroy()
		end
		local hat = game.ReplicatedStorage.Clothes.Hats.Hat1:Clone()
		hat.Parent = clone
		local weld = Instance.new("Weld")
		weld.Parent = clone.Head
		weld.Name = "HeadWeld"
		weld.Part0 = hat.Handle
		weld.Part1 = clone.Head
		weld.C0 = CFrame.new(0, -.7, 0)
	else
		Hats.Hat1.IfWearing.Value = false
		if clone:FindFirstChild("Hat1") then
			clone.Hat1:Destroy()
		end
	end
end)

Hats.Hat2.MouseButton1Click:Connect(function()
	if Hats.Hat2.IfWearing.Value == false then
		Hats.Hat2.IfWearing.Value = true
		if clone:FindFirstChild("Hat1") then
			clone.Hat1:Destroy()
		end
		if clone:FindFirstChild("Hat3") then
			clone.Hat3:Destroy()
		end
		local hat = game.ReplicatedStorage.Clothes.Hats.Hat2:Clone()
		hat.Parent = clone
		local weld = Instance.new("Weld")
		weld.Parent = clone.Head
		weld.Name = "HeadWeld"
		weld.Part0 = hat.Handle
		weld.Part1 = clone.Head
		weld.C0 = CFrame.new(-.05, -.5, 0)
	else
		Hats.Hat2.IfWearing.Value = false
		if clone:FindFirstChild("Hat2") then
			clone.Hat2:Destroy()
		end
	end
end)

Hats.Hat3.MouseButton1Click:Connect(function()
	if Hats.Hat3.IfWearing.Value == false then
		Hats.Hat3.IfWearing.Value = true
		if clone:FindFirstChild("Hat1") then
			clone.Hat1:Destroy()
		end
		if clone:FindFirstChild("Hat2") then
			clone.Hat2:Destroy()
		end
		local hat = game.ReplicatedStorage.Clothes.Hats.Hat3:Clone()
		hat.Parent = clone
		local weld = Instance.new("Weld")
		weld.Parent = clone.Head
		weld.Name = "HeadWeld"
		weld.Part0 = hat.Handle
		weld.Part1 = clone.Head
		weld.C0 = CFrame.new(0, -.2, 0)
	else
		Hats.Hat3.IfWearing.Value = false
		if clone:FindFirstChild("Hat3") then
			clone.Hat3:Destroy()
		end
	end
end)
--------------------------------------------------------------------------------------------------
--Shirts
local Shirts = selectionframes.ShirtSelectionFrame


Shirts.Shirt1.MouseButton1Click:Connect(function()
	if Shirts.Shirt1.IfWearing.Value == false then
		Shirts.Shirt1.IfWearing.Value = true
		if clone:FindFirstChildWhichIsA("Shirt") then
			shirt = clone:FindFirstChildWhichIsA("Shirt")
			shirt.ShirtTemplate = "http://www.roblox.com/asset/?id=1174846799"
		else
			shirt = Instance.new("Shirt")
			shirt.Parent = clone
			shirt.ShirtTemplate = "http://www.roblox.com/asset/?id=1174846799"
		end
	else
		if game.Players.LocalPlayer.Character:FindFirstChildWhichIsA("Shirt") then
			shirt.ShirtTemplate = game.Players.LocalPlayer.Character.Shirt.ShirtTemplate
			Shirts.Shirt1.IfWearing.Value = false
		else
			shirt:Destroy()
			Shirts.Shirt1.IfWearing.Value = false
		end
	end
end)

Shirts.Shirt2.MouseButton1Click:Connect(function()
	if Shirts.Shirt2.IfWearing.Value == false then
		Shirts.Shirt2.IfWearing.Value = true
		if clone:FindFirstChildWhichIsA("Shirt") then
			shirt = clone:FindFirstChildWhichIsA("Shirt")
			shirt.ShirtTemplate = "http://www.roblox.com/asset/?id=4800855967"
		else
			shirt = Instance.new("Shirt")
			shirt.Parent = clone
			shirt.ShirtTemplate = "http://www.roblox.com/asset/?id=4800855967"
		end
	else
		if game.Players.LocalPlayer.Character:FindFirstChildWhichIsA("Shirt") then
			shirt.ShirtTemplate = game.Players.LocalPlayer.Character.Shirt.ShirtTemplate
			Shirts.Shirt2.IfWearing.Value = false
		else
			shirt:Destroy()
			Shirts.Shirt2.IfWearing.Value = false
		end
	end
end)

Shirts.Shirt3.MouseButton1Click:Connect(function()
	if Shirts.Shirt3.IfWearing.Value == false then
		Shirts.Shirt3.IfWearing.Value = true
		if clone:FindFirstChildWhichIsA("Shirt") then
			shirt = clone:FindFirstChildWhichIsA("Shirt")
			shirt.ShirtTemplate = "http://www.roblox.com/asset/?id=3769979025"
		else
			shirt = Instance.new("Shirt")
			shirt.Parent = clone
			shirt.ShirtTemplate = "http://www.roblox.com/asset/?id=3769979025"
		end
	else
		if game.Players.LocalPlayer.Character:FindFirstChildWhichIsA("Shirt") then
			shirt.ShirtTemplate = game.Players.LocalPlayer.Character.Shirt.ShirtTemplate
			Shirts.Shirt3.IfWearing.Value = false
		else
			shirt:Destroy()
			Shirts.Shirt3.IfWearing.Value = false
		end
	end
end)
--------------------------------------------------------------------------------------------------
--Pants
local Pants = selectionframes.PantsSelectionFrame


Pants.Pants1.MouseButton1Click:Connect(function()
	if Pants.Pants1.IfWearing.Value == false then
		Pants.Pants1.IfWearing.Value = true
		if clone:FindFirstChildWhichIsA("Pants") then
			pant = clone:FindFirstChildWhichIsA("Pants")
			pant.PantsTemplate = "http://www.roblox.com/asset/?id=129458425"
		else
			pant = Instance.new("Pants")
			pant.Parent = clone
			pant.PantsTemplate = "http://www.roblox.com/asset/?id=129458425"
		end
	else
		if game.Players.LocalPlayer.Character:FindFirstChildWhichIsA("Pants") then
			pant.PantsTemplate = game.Players.LocalPlayer.Character.Pants.PantsTemplate
			Pants.Pants1.IfWearing.Value = false
		else
			pant:Destroy()
			Pants.Pants1.IfWearing.Value = false
		end
	end
end)

Pants.Pants2.MouseButton1Click:Connect(function()
	if Pants.Pants2.IfWearing.Value == false then
		Pants.Pants2.IfWearing.Value = true
		if clone:FindFirstChildWhichIsA("Pants") then
			pant = clone:FindFirstChildWhichIsA("Pants")
			pant.PantsTemplate = "http://www.roblox.com/asset/?id=4767255047"
		else
			pant = Instance.new("Pants")
			pant.Parent = clone
			pant.PantsTemplate = "http://www.roblox.com/asset/?id=4767255047"
		end
	else
		if game.Players.LocalPlayer.Character:FindFirstChildWhichIsA("Pants") then
			pant.PantsTemplate = game.Players.LocalPlayer.Character.Pants.PantsTemplate
			Pants.Pants2.IfWearing.Value = false
		else
			pant:Destroy()
			Pants.Pants2.IfWearing.Value = false
		end
	end
end)

Pants.Pants3.MouseButton1Click:Connect(function()
	if Pants.Pants3.IfWearing.Value == false then
		Pants.Pants3.IfWearing.Value = true
		if clone:FindFirstChildWhichIsA("Pants") then
			pant = clone:FindFirstChildWhichIsA("Pants")
			pant.PantsTemplate = "http://www.roblox.com/asset/?id=730590583"
		else
			pant = Instance.new("Pants")
			pant.Parent = clone
			pant.PantsTemplate = "http://www.roblox.com/asset/?id=730590583"
		end
	else
		if game.Players.LocalPlayer.Character:FindFirstChildWhichIsA("Pants") then
			pant.PantsTemplate = game.Players.LocalPlayer.Character.Pants.PantsTemplate
			Pants.Pants3.IfWearing.Value = false
		else
			pant:Destroy()
			Pants.Pants3.IfWearing.Value = false
		end
	end
end)
--------------------------------------------------------------------------------------------------
--Backpacks
local Backs = selectionframes.BackSelectionFrame


Backs.Back1.MouseButton1Click:Connect(function()
	if Backs.Back1.IfWearing.Value == false then
		Backs.Back1.IfWearing.Value = true
		if clone:FindFirstChild("Back2") then
			clone.Back2:Destroy()
		end
		if clone:FindFirstChild("Back3") then
			clone.Back3:Destroy()
		end
		local back = game.ReplicatedStorage.Clothes.Back.Back1:Clone()
		back.Parent = clone
		back.AttachmentRight = Vector3.new(0.5, 0, 0)
		local weld = Instance.new("Weld")
		weld.Parent = back.Handle
		weld.Name = "AccessoryWeld"
		weld.Part0 = back.Handle
		weld.Part1 = clone.Torso
		weld.C0 = CFrame.new(0, 0, -.4)
	else
		Backs.Back1.IfWearing.Value = false
		if clone:FindFirstChild("Back1") then
			clone.Back1:Destroy()
		end
	end
end)

Backs.Back2.MouseButton1Click:Connect(function()
	if Backs.Back2.IfWearing.Value == false then
		Backs.Back2.IfWearing.Value = true
		if clone:FindFirstChild("Back1") then
			clone.Back1:Destroy()
		end
		if clone:FindFirstChild("Back3") then
			clone.Back3:Destroy()
		end
		local back = game.ReplicatedStorage.Clothes.Back.Back2:Clone()
		back.Parent = clone
		back.AttachmentRight = Vector3.new(0.5, 0, 0)
		local weld = Instance.new("Weld")
		weld.Parent = back.Handle
		weld.Name = "AccessoryWeld"
		weld.Part0 = back.Handle
		weld.Part1 = clone.Torso
		weld.C0 = CFrame.new(0, -.3, -.4)
	else
		Backs.Back2.IfWearing.Value = false
		if clone:FindFirstChild("Back2") then
			clone.Back2:Destroy()
		end
	end
end)

Backs.Back3.MouseButton1Click:Connect(function()
	if Backs.Back3.IfWearing.Value == false then
		Backs.Back3.IfWearing.Value = true
		if clone:FindFirstChild("Back1") then
			clone.Back1:Destroy()
		end
		if clone:FindFirstChild("Back2") then
			clone.Back2:Destroy()
		end
		local back = game.ReplicatedStorage.Clothes.Back.Back3:Clone()
		back.Parent = clone
		back.AttachmentRight = Vector3.new(0.5, 0, 0)
		local weld = Instance.new("Weld")
		weld.Parent = back.Handle
		weld.Name = "AccessoryWeld"
		weld.Part0 = back.Handle
		weld.Part1 = clone.Torso
		weld.C0 = CFrame.new(0, -.3, -.9)
	else
		Backs.Back3.IfWearing.Value = false
		if clone:FindFirstChild("Back3") then
			clone.Back3:Destroy()
		end
	end
end)

Would I save the model and put it into database perhaps? (I don’t really understand saving data yet so I may be wrong.)

2 Likes

I am pretty sure the DataStoreService cannot save models and stuff like that. It can store string values, integers and bool values (don’t take my word for it though!). What I would suggest is to encode the character customisation of a player into a string value/int value. An example:
Player Customisation:
Cowboy Hat
Green Hair
Cool Shirt
Cool Pants
Epec shoes.

Encoded:
HatCowboyHairGreenShirtCoolPantsCoolShoesEpec

Later when this data is retrieved, you could encode it, fetch whatever is needed and place it into the character. I hope this makes sense! Tell me if you didn’t understand it so I can help!

2 Likes

You have to assign every accessory a code, the player will have an hat value and when the player wears an accessory the value will become the code assigned to the chosen accessory. Then you will save the hat value in the datastore and script a system that gives the player an accessory depending on the hat value.
Or at least, that’s how I do it, I hope my explanation is understandable.
Also this is the wrong category, this goes in #help-and-feedback:scripting-support

Example:
A player choses to wear a pair of wings

  • The hat value gets set to 1
  • You store the hat value in the datastore
    The player leaves and then rejoins
  • You load the datastore
  • A script checks the hat value and since it’s equal to 1 it gives him the pair of wings
1 Like

Hey, I just did what you recommended and it worked! But I have one issue… It saves one clothing piece… When I print out what I saved it only prints 1 clothing piece in the output. How would I store multiple pieces? Thanks.

My code:

local DataStoreService = game:GetService("DataStoreService")

local playerData = DataStoreService:GetDataStore("PlayerData")


game.ReplicatedStorage.Events.SaveCustomisation.OnServerEvent:Connect(function(player, Names)
	local playerUserId = "Player_" .. player.UserId
	playerData:SetAsync(playerUserId, Names)
end)


local function onPlayerJoin(player)
	local playerUserId = "Player_" .. player.UserId
	local data = playerData:GetAsync(playerUserId)

	if data then
		--game.ReplicatedStorage.Events.SaveCustomisation:FireAllClients(data)
		print(data)
	else
		print("No clothes ( ͡° ͜ʖ ͡°)")
	end
end

client code:

script.Parent.SaveButton.MouseButton1Click:Connect(function()
	local debounce = false
	if debounce == false then
		debounce = true
		for i,v in pairs(selectionframes:GetDescendants()) do
			if v:IsA("BoolValue") then
				if v.Value == true then
					game.ReplicatedStorage.Events.SaveCustomisation:FireServer(v.Parent.Name)
				end
			end
		end
		wait(10)
		debounce = false
	else
		print("please wait 10 seconds before saving again.")
	end
end)

Output although I attempt to store multiple clothing pieces:
plsno

Maybe you will know the answer to my question that I asked to @Lightning_Game27 ?

I think you need to move this to #help-and-feedback:scripting-support

Whoops my bad, this is my first post and it was kinda confusing on how to set it up. Thanks anyway, I’ll try to remember next time.

No worries!

Back to topic, you should save values to datastores, not models.

Models wont do anything. Make values.

I’ve got to the point that I need to store values, but I’m just not sure how to store multiple of them.

Maybe store the values inside of a table and then defining it in a Data Store?

These posts should be helpful for you.

Saving items to an inventory - #9 by Soybeen

and

Use a table that stores the names of the objects and when player joins retrieve the objects from replicated storage and apply them to the player. Example of ds in a table form
[UserId] ={[“customization”]= {
[“hat”]= nil,
[“Shirt”] = nil,
["Pants] = nil,

}
}

2 Likes

Think of datastores as tables/dictionaries because that’s what they are. You can save data exactly the way you would alter a table.