How to save Color3 to datastore?

local saveslot1 = game:GetService("DataStoreService"):GetDataStore("SlotSave100")

function SaveData1(player,character)
	local face
	local skincolor
	for i,v in pairs(player.Character.Head:GetChildren()) do
		if v:IsA("Decal") then
			face = v
		end
	end
	for f,k in pairs(player.Character:GetChildren()) do
		if k:IsA("MeshPart") then
			skincolor = k
		end
	end
	local charactercustom = {
		["Face"] = face.Texture,
		["SkinColor"] = {skincolor.Color.r,skincolor.Color.g,skincolor.Color.b}
	}
	local suc,err = pcall(function()
		saveslot1:SetAsync(player.UserId,charactercustom)
	end)
	print(player.Name, "DataStoreRetrivalInformation", suc, err)
end

function LoadData1(player,Character)
	local charactercustom
	local suc,err = pcall(function()
		charactercustom = saveslot1:GetAsync(player.UserId)
	end)	
	if charactercustom then
	print(player.Name, "DataStoreRetrivalInformation", suc, err)
	for i,v in pairs(player.Character.Head:GetChildren()) do
		if v:IsA("Decal") then
				v.Texture = charactercustom["Face"]
			end
		end
		for i,v in pairs(Character:GetChildren()) do
			if v:IsA("MeshPart") then
				v.Color = Color3.fromRGB(charactercustom["SkinColor"][1],charactercustom["SkinColor"][2],charactercustom["SkinColor"][3])
			end
		end
	end
end

game.Players.PlayerAdded:Connect(function(player)
	--repeat wait() until player.Character
	player.CharacterAdded:Connect(function(char)
		LoadData1(player,char)
	end)
end)

game:BindToClose(function()
	for _,player in pairs(game.Players:GetPlayers()) do
		SaveData1(player)
	end
end)

game.Players.PlayerRemoving:Connect(function(plr)
	--repeat wait() until plr.Character
	local char = plr.Character or plr.CharacterAdded:Wait()
	SaveData1(plr,char)
end)

I want to save the Color3 values to datastores. It saves but when I look at the array in DataStore Editor, it shows a bunch of random numbers instead of the actual Color3 values.

2 Likes

There are several MeshParts in Character.
I don’t think it is what you want to save.

1 Like

I want to save the characters color3 values into the dictionary.

Oh i misunderstood
You saved the table instead of Color3
Datastore can save only String and Table.

1 Like

There is already something related to this topic.

1 Like
--Save to datastore

local SaveColor3 = Color3.new()--color3 to save

local SaveToDatastore = {SaveColor3.R,SaveColor3.G,SaveColor3.B} --save to datastore

datastore:SetAsync(key,SaveToDatastore)

--Load from datastore

local DataFromDatastore = datastore:GetAsync(key) --load from datastore

local LoadedColor3 = Color3.new(DataFromDatastore.R,DataFromDatastore.G,DataFromDatastore.B)
1 Like

That didn’t work, still gave me the same results with no errors.

1 Like

There have been many topics on this in the past. Options include:

  • Saving the red, green and blue components in a table
  • Converting to hex codes and saving that
  • Converting to an integer and saving that

You are currently doing the first one, which is absolutely fine.

Your issue is due to you putting the Character children loop inside of the Head children loop using the same variables i and v.

Edit: I misread initially so I’ve updated the cause here.

5 Likes

I would save the red, greed and blue components in separate numbers or a string and then just use them.

Yes, but can i just save the whole Color3 directly instead of saving each component?

I dont think, you would need to try it.

1 Like

I feel pretty stupid for not seeing that, so thank you. That hasn’t solved my issue though.

1 Like

So what exactly is the issue you’re seeing? Just confusing numbers in the datastore editor?

If the numbers are fractional between 0 and 1, then that’s the Color3 values as they should be.

Does the actual loading and setting of the skin colour now work? If so, then there isn’t a problem.

The saving seems to be working, but the loading and setting of the skin color isn’t.

1 Like

When you ask a Color3 component (R,G,B property) they don’t return their usual 0-255 range.

If you insert a Part and print(workspace.Part.Color.R) you’re going to get a decimal number in the output. You’d need to convert that into it’s original 0-255 range.

local LoadedCustom = saveslot1:GetAsync(player.UserId)
local SkinColor = LoadedCustom["SkinColor"]

local LoadedColor3 = Color3.fromRGB(SkinColor[1] * 255, SkinColor[2] * 255, SkinColor[3] * 255)
1 Like

That didn’t seem to work. It loads the face but not the skin color.

1 Like

Or just use Color3.new and don’t bother with the conversion, but that’s a great spot. That’s probably why OP feels like they get random numbers.

2 Likes

Have you tried using the BodyColors object that exists for this exact purpose, instead of colouring parts?

You also may find that not all the body parts exist when CharacterAdded is fired, so BodyColors is a safe method.

1 Like

I thought about using BodyColors, but wouldn’t I have to write multiple keys inside of the dictionary since I can’t for loop it.

1 Like

Currently you set all the parts to the same colour, so you’d just do that for each property of BodyColors. There’s six properties so it would be six lines of code for the setting:

local loadedColor = Color3.new(charactercustom.SkinColor[1], charactercustom.SkinColor[2], charactercustom.SkinColor[3])
local bodyColors = Character:WaitForChild("Body Colors")
-- Set the properties
bodyColors.HeadColor3 = loadedColor
bodyColors.LeftArmColor3 = loadedColor
bodyColors.LeftLegColor3 = loadedColor
bodyColors.RightArmColor3 = loadedColor
bodyColors.RightLegColor3 = loadedColor
bodyColors.TorsoColor3 = loadedColor
3 Likes

That seemed to work! Thanks so much! One question, what if I wanted to save accessories?

1 Like

I think you would need to save all links (meshlinks for example), texturelinks etc. I would save these as a string and all positions as numbers (or Vector3 values) and then just, when you are creating a new accessory, use these strings. This should not be to hard. Make sure to save everthing separately.

1 Like