I have made a similar code using data stores but it could only save one part at a time, I’m wondering if you can use one data stores to store multiple parts color property.
Alright I will take a look at it.
For example:
-- manually creating a dictionary
local partColours = {
["PartOne"] = BrickColor.new("Really red")
}
-- adding to the dictionary
local partColours = {}
local part = workspace.PartOne
partColours[part.Name] = part.BrickColor
-- output; same for both methods
{
["PartOne"] = Really red
}
Alternatively, you can save the part as the index instead of just its name, if required
Okay thank you very much!
If I encounter problems I’ll hit you up
You can’t store BrickColor objects inside DataStores as they are considered custom userdata, you need to serialize them beforehand.
local function serializeBrickColor(brickColor : BrickColor)
return brickColor.Name
end
local function deserializeBrickColor(brickColorName : string)
return BrickColor.new(brickColorName)
end
local brickColor = BrickColor.new() --Creates a default BrickColor object.
local serializedBrickColor = serializeBrickColor(brickColor)
print(serializedBrickColor, type(serializedBrickColor)) --Really black string
local deserializedBrickColor = deserializeBrickColor(serializedBrickColor)
print(deserializedBrickColor, type(deserializedBrickColor)) --Really black userdata
Also if you want more accurate coloring, since BrickColors round to the nearest available color in the brickcolor list. You can store the RGB of a part as a table like so:
local t = {}
t.R = part.Color.R
t.G = part.Color.G
t.B = part.Color.B
-- TODO: save t
-- then you can load the table and do:
part.Color = Color3.fromRGB(t.R, t.G, t.B)
here is how to save and load colors to multiple parts
local dataStoreService = game:GetService("DataStoreService")
local dataStore = dataStoreService:GetDataStore("PartColors")
-- get all parts from the Parts folder
local parts = game.Workspace.Parts:GetChildren()
-- loop all parts and add the hex string to the data table
-- we use hex because it will use less characters we have a limit 4,000,000 characters
-- each part needs to have a unique name so we no what color to give the part when we load the color data back
local data = {}
for i, part in ipairs(parts) do
data[part.Name] = part.Color:ToHex()
end
-- save the data to the datastore
local success, returned = pcall(dataStore.SetAsync, dataStore, "colors", data)
if success == false then print("Failed to save") end
-- load the data from the datastore
local success, returned = pcall(dataStore.GetAsync, dataStore, "colors")
if success == false then print("Failed to load") end
-- loop each hex in the data and set the parts color
for name, hex in pairs(returned) do
game.Workspace.Parts[name].Color = Color3.fromHex(hex)
end
I’ve used this barbaric method to save data of each part, so basically I have added a BoolValue to each part and used for i loops to get every BoolValue, as expected It did not really work, btw here’s the code.
local DataStore = game:GetService('DataStoreService')
local MyDataStore = DataStore:GetDataStore('Data_')
local ReplicatedStorage = game:GetService('ReplicatedStorage')
local ChangeValue = ReplicatedStorage.RemoteEvent:WaitForChild('ChangeValue')
local Parts = workspace.Parts
local Players = game.Players
Players.PlayerAdded:Connect(function(player)
local key = 'id_'..player.UserId
for i, v in pairs(Parts:GetChildren()) do
if v:isA('Part') then
local BoolVal = v:FindFirstChildOfClass('BoolValue')
local data = MyDataStore:GetAsync(key)
if data then
BoolVal.Value = data
else
MyDataStore:GetAsync(key, BoolVal)
end
if BoolVal.Value == true then
v.BrickColor = BrickColor.new('Lime green')
else
v.BrickColor = BrickColor.new('Medium Medium stone grey')
end
end
end
end)
Players.PlayerRemoving:Connect(function(player)
local key = 'id_'..player.UserId
for i, v in pairs(Parts:GetChildren()) do
if v:isA('Part') then
local BoolVal = v:FindFirstChildOfClass('BoolValue')
local data = BoolVal.Value
MyDataStore:SetAsync(key, data)
end
end
end)
For some reason this code doesn’t work for me strangely.
local dataStoreService = game:GetService("DataStoreService")
local dataStore = dataStoreService:GetDataStore("PartColors")
local Players = game.Players
-- get all parts from the Parts folder
local parts = game.Workspace.Parts:GetChildren()
-- loop all parts and add the hex string to the data table
-- we use hex because it will use less characters we have a limit 4,000,000 characters
-- each part needs to have a unique name so we no what color to give the part when we load the color data back
local data = {}
for i, part in ipairs(parts) do
data[part.Name] = part.Color:ToHex()
end
Players.PlayerAdded:Connect(function()
-- load the data from the datastore
local success, returned = pcall(dataStore.GetAsync, dataStore, "colors")
if success == false then print("Failed to load") end
for name, hex in pairs(returned) do
game.Workspace.Parts[name].Color = Color3.fromHex(hex)
end
end)
Players.PlayerRemoving:Connect(function()
-- save the data to the datastore
local success, returned = pcall(dataStore.SetAsync, dataStore, "colors", data)
if success == false then print("Failed to save") end
end)
Tried adding in the PlayerAdded function and PlayerRemoving function to see if it would get fixed, but still the data isn’t getting saved and there’s nothing in the output.
it does not really make sense to save and load the same data over and over again every time a player enters or exits the game
also if your testing in studio there is a chance that when you stop the game there is not enough time to save the data into datastore when using PlayerRemoving so the colors are not getting saved so here is how you can load and save when the server starts and stops
https://developer.roblox.com/en-us/api-reference/function/DataModel/BindToClose
will stop the server from shutting down for up to 30 seconds and that’s enough time to allow us to save the data into the datastore
local dataStoreService = game:GetService("DataStoreService")
local dataStore = dataStoreService:GetDataStore("PartColors")
local success, data = pcall(dataStore.GetAsync, dataStore, "colors")
if success == false then print("Failed to load part colors") return end
for name, hex in pairs(data) do
game.Workspace.Parts[name].Color = Color3.fromHex(hex)
end
game:BindToClose(function()
local data = {}
for i, part in ipairs(game.Workspace.Parts:GetChildren()) do
data[part.Name] = part.Color:ToHex()
end
local success, returned = pcall(dataStore.SetAsync, dataStore, "colors", data)
if success == false then print("Failed to save part colors") end
end)
Yes, we can. BrickColor is not a UTF8 character, thus it cannot be saved. Instead, we’ll have to turn it into UTF8. So, it works something like this:
local store = game:GetService("DataStoreService"):GetDataStore("ColourStore")
local part = Instance.new("Part")
part.Anchored = true
part:PivotTo(CFrame.new(Vector3.new(0,5,0)))
part.BrickColor = BrickColor.Random()
part.Parent = workspace
local colourarray = {
part.BrickColor.Color3.R,
part.BrickColor.Color3.G,-- We can just save the name of the brickcolorz but I like this method
part.BrickColor.Color3.B,
}
local success = pcall(function()
store:UpdateAsync("COLOUR",function()
return colourarray
end)
end)
if (success) then
part:Destroy()
task.wait(5)
local success, data = pcall(function()
return store:GetAsync("COLOUR") --retrieving the serialized data
end)
if (success and data) then
local p = Instance.new("Part")
p.Anchored = true
p:PivotTo(CFrame.new(Vector3.new(10,5,10)))
p.Color3 = Color3.fromRGB(data[1],data[2],data[3])
p.Parent = workspace
end
end
I hoped this helped.
If I want to use this script on Multiple parts that are on a folder do I have to do:
local Folder = workspace.Folder:GetChildren()
?
That script was just an example script on how to convert the BrickColor
of a part into UTF8 format. If you read the script, you may get a better understanding on saving them. But sure, we can do that.
local store = game:GetService("DataStoreService"):GetDataStore("PartColours")
local save = {}
function convert(part:BasePart)
return {
part.BrickColor.Name
}
end
local folder = workspace.Folder
for i, part in ipairs(Folder:GetChildren()) do
local converted = convert(part)
save[part.Name] = converted
end
local success = pcall(function()
store:UpdateAsync("key",function()
return save
end)
end)