Hello guys, I’m trying to make a saving system for my building game, everything seems to work but I have a problem with the orientation, the orientation doesn’t save, when I try to load my builds that I made everything seems to be saved except the rotation of parts, can anyone help me solve this?
Code:
local players = game:GetService("Players")
local dataStoreService = game:GetService("DataStoreService")
local autoSavingStore = dataStoreService:GetDataStore("F3XSave")
local nameStore = dataStoreService:GetDataStore("NameSaves")
local keyPrefix = "Player_"
local function serialize(obj: Instance | any)
local _, properties = pcall(function()
local r = {}
r.Name = obj.Name
r.ClassName = obj.ClassName
r.Children = {}
if obj:IsA("BasePart") then
r.CanCollide = obj.CanCollide
r.CFrameX = obj.CFrame.X
r.CFrameY = obj.CFrame.Y
r.CFrameZ = obj.CFrame.Z
r.OrientationX = obj.Orientation.X
r.OrientationY = obj.Orientation.Y
r.OrientationZ = obj.Orientation.Z
r.SizeX = obj.Size.X
r.SizeY = obj.Size.Y
r.SizeZ = obj.Size.Z
r.ColorR = obj.Color.R
r.ColorG = obj.Color.G
r.ColorB = obj.Color.B
r.TopSurface = (string.match(tostring(obj.TopSurface), "%.(%w+)$"))
r.BottomSurface = (string.match(tostring(obj.BottomSurface), "%.(%w+)$"))
r.LeftSurface = (string.match(tostring(obj.LeftSurface), "%.(%w+)$"))
r.RightSurface = (string.match(tostring(obj.RightSurface), "%.(%w+)$"))
r.BackSurface = (string.match(tostring(obj.BackSurface), "%.(%w+)$"))
r.FrontSurface = (string.match(tostring(obj.FrontSurface), "%.(%w+)$"))
r.Transparency = obj.Transparency
r.Reflectance = obj.Reflectance
r.Material = string.match(tostring(obj.Material), "%.(%w+)$")
r.VelocityX = obj.Velocity.X
r.VelocityY = obj.Velocity.Y
r.VelocityZ = obj.Velocity.Z
r.Anchored = obj.Anchored
elseif obj:IsA("Decal") then
-- Handle Decal properties
r.Texture = obj.Texture
r.Face = tostring(obj.Face.Name)
r.Transparency = obj.Transparency
r.IColorR = obj.Color3.R
r.IColorG = obj.Color3.G
r.IColorB = obj.Color3.B
elseif obj:IsA("Texture") then
r.Texture = obj.Texture
r.Face = tostring(obj.Face.Name)
r.Transparency = obj.Transparency
r.IColorR = obj.Color3.R
r.IColorG = obj.Color3.G
r.IColorB = obj.Color3.B
r.OffsetStudsU = obj.OffsetStudsU
r.OffsetStudsV = obj.OffsetStudsV
r.StudsPerTileU = obj.StudsPerTileU
r.StudsPerTileV = obj.StudsPerTileV
elseif obj:IsA("SpecialMesh") then
r.MeshId = obj.MeshId
r.MeshType = obj.MeshType.Name
r.TextureId = obj.TextureId
r.OffsetX = obj.Offset.X
r.OffsetY = obj.Offset.Y
r.OffsetZ = obj.Offset.Z
r.ScaleX = obj.Scale.Z
r.ScaleY = obj.Scale.Y
r.ScaleZ = obj.Scale.Z
elseif obj:IsA("PointLight") then
r.Brightness = obj.Brightness
r.Enabled = obj.Enabled
r.ColorR = obj.Color.R
r.ColorG = obj.Color.G
r.ColorB = obj.Color.B
r.Range = obj.Range
r.Shadows = obj.Shadows
elseif obj:IsA("SpotLight") then
r.Brightness = obj.Brightness
r.Face = obj.Face.Name
r.Enabled = obj.Enabled
r.ColorR = obj.Color.R
r.ColorG = obj.Color.G
r.ColorB = obj.Color.B
r.Angle = obj.Angle
r.Range = obj.Range
r.Shadows = obj.Shadows
elseif obj:IsA("SurfaceLight") then
r.Brightness = obj.Brightness
r.Face = obj.Face.Name
r.Enabled = obj.Enabled
r.ColorR = obj.Color.R
r.ColorG = obj.Color.G
r.ColorB = obj.Color.B
r.Angle = obj.Angle
r.Range = obj.Range
r.Shadows = obj.Shadows
elseif obj:IsA("SurfaceGui") then
r.AlwaysOnTop = obj.AlwaysOnTop
r.Face = obj.Face.Name
r.Brightness = obj.Brightness
r.LightInfluence = obj.LightInfluence
r.MaxDistance = obj.MaxDistance
elseif obj:IsA("TextLabel") then
r.BackgroundColor3R = obj.BackgroundColor3.R
r.BackgroundColor3G = obj.BackgroundColor3.G
r.BackgroundColor3B = obj.BackgroundColor3.B
r.BackgroundTransparency=obj.BackgroundTransparency
r.BorderColor3R = obj.BorderColor3.R
r.BorderColor3G = obj.BorderColor3.G
r.BorderColor3B = obj.BorderColor3.B
r.BorderMode = obj.BorderMode.Name
r.BorderSizePixel = obj.BorderSizePixel
r.Rotation = obj.Rotation
r.UISizeX = tostring(obj.Size.X)
r.UISizeY = tostring(obj.Size.Y)
r.Visible = obj.Visible
r.Font = obj.Font.Name
r.RichText = obj.RichText
r.Text = obj.Text
r.TextColor3R = obj.TextColor3.R
r.TextColor3G = obj.TextColor3.G
r.TextColor3B = obj.TextColor3.B
r.TextScaled = obj.TextScaled
r.TextSize = obj.TextSize
r.TextStrokeTransparency = obj.TextStrokeTransparency
r.TextTransparency = obj.TextTransparency
elseif obj:IsA("StringValue") then
r.Value = obj.Value
r.Name = obj.Name
elseif obj:IsA("VehicleSeat") then
r.Parent = obj.Parent
r.Name = obj.Name
r.Disabled = obj.Disabled
r.MaxSpeed = obj.MaxSpeed
r.Steer = obj.Steer
r.SteerFloat = obj.SteerFloat
r.Throttle = obj.Throttle
r.ThrottleFloat = obj.ThrottleFloat
r.Torque = obj.Torque
r.TurnSpeed = obj.TurnSpeed
elseif obj:IsA("Model") then
r.Name = obj.Name
else
-- Nothing
end
return r
end)
for i, v in pairs(obj:GetChildren()) do
table.insert(properties.Children, serialize(v))
end
return properties
end
local function save(player: Player, Slot, text)
local key = keyPrefix .. tostring(player.UserId)
local data = {}
for i, obj: BasePart in ipairs(workspace:FindFirstChild("F3XFolder"):WaitForChild(player.Name.."'s Folder"):GetDescendants()) do
if obj:IsA("BasePart") then
if obj.Parent:IsA("Model") then continue end
local s, serializedTable = pcall(function()
return serialize(obj)
end)
if typeof(serializedTable) == "string" then
warn(serializedTable)
continue
end
table.insert(data, serializedTable)
elseif obj:IsA("Model") then
local s, serializedTable = pcall(function()
return serialize(obj)
end)
if typeof(serializedTable) == "string" then
warn(serializedTable)
continue
end
table.insert(data, serializedTable)
end
end
local success, err = pcall(function()
print(data)
autoSavingStore:SetAsync(tostring(player.UserId).." -slot"..tostring(Slot), data)
if player.PlayerGui:WaitForChild("SavingUI") then
if text ~= nil then
nameStore:SetAsync(tostring(player.UserId).." -sl"..tostring(Slot), text)
end
end
end)
if not success then
warn(tostring(err))
end
end
local function load(player: Player, Slot)
local key = tostring(player.UserId).." -slot"..tostring(Slot)
local key2 = tostring(player.UserId).." -sl"..tostring(Slot)
local success, err
local data
local data2
repeat
success, err = pcall(function()
data = autoSavingStore:GetAsync(key)
data2 = nameStore:GetAsync(key2)
end)
until success or not players:FindFirstChild(player.Name)
if not data then return end
if success then
print(data2)
if player.PlayerGui:WaitForChild("SavingUI") then
player.PlayerGui.SavingUI.MainFrame.SaveList["Slot"..Slot].SlotTitle.Text = tostring(data2)
end
for i, objData in pairs(data) do
local function createInstance(objData)
local instance
if objData.Name and objData.ClassName then
instance = Instance.new(objData.ClassName)
instance.Name = objData.Name
for property, value in pairs(objData) do
if property ~= "Name" and property ~= "ClassName" and property ~= "Children" then
if property == "CFrameX" or property == "CFrameY" or property == "CFrameZ" then
instance.CFrame = CFrame.new(objData.CFrameX, objData.CFrameY, objData.CFrameZ)
elseif property == "OrientationX" or property == "OrientationY" or property == "OrientationZ" then
instance.Orientation = Vector3.new(objData.OrientationX, objData.OrientationY, objData.OrientationZ)
elseif property == "ColorR" or property == "ColorG" or property == "ColorB" then
instance.Color = Color3.new(objData.ColorR, objData.ColorG, objData.ColorB)
elseif property == "IColorR" or property == "IColorG" or property == "IColorB" then
instance.Color3 = Color3.new(objData.IColorR, objData.IColorR, objData.IColorR)
elseif property == "SizeX" or property == "SizeY" or property == "SizeZ" then
instance.Size = Vector3.new(objData.SizeX, objData.SizeY, objData.SizeZ)
elseif property == "ScaleX" or property == "ScaleY" or property == "ScaleZ" then
instance.Scale = Vector3.new(objData.ScaleX, objData.ScaleY, objData.ScaleZ)
elseif property == "OffsetX" or property == "OffsetY" or property == "OffsetZ" then
instance.Offset = Vector3.new(objData.OffsetX, objData.OffsetY, objData.OffsetZ)
elseif property == "SecondaryColorR" or property == "SecondaryColorG" or property == "SecondaryColorB" then
instance.Color = Color3.new(objData.SecondaryColorR, objData.SecondaryColorG, objData.SecondaryColorB)
elseif property == "UISizeX" or property == "UISizeY" then
instance.Size = UDim2.new({1,0}, {1,0})
elseif property == "TextColor3R" or property == "TextColor3G" or property == "TextColor3B" then
instance.TextColor3 = Color3.new(objData.TextColor3R, objData.TextColor3G, objData.TextColor3B)
elseif property == "BackgroundColor3R" or property == "BackgroundColor3G" or property == "BackgroundColor3B" then
instance.BackgroundColor3 = Color3.new(objData.BackgroundColor3R, objData.BackgroundColor3G, objData.BackgroundColor3B)
elseif property == "BorderColor3R" or property == "BorderColor3G" or property == "BorderColor3B" then
instance.BorderColor3 = Color3.new(objData.BorderColor3R, objData.BorderColor3G, objData.BorderColor3B)
elseif property == "VelocityX" or property == "VelocityY" or property == "VelocityZ" then
instance.Velocity = Vector3.new(objData.VelocityX, objData.VelocityY, objData.VelocityZ)
else
instance[property] = value
end
end
end
if objData.Children then
for _, childData in ipairs(objData.Children) do
local childInstance = createInstance(childData)
childInstance.Parent = instance
end
end
end
return instance
end
local partInstance = createInstance(objData)
if partInstance then
partInstance.Parent = workspace.F3XFolder:WaitForChild(player.Name.."'s Folder") -- Adjust the hierarchy based on your structure
end
end
else
warn(tostring(err))
end
end
game.ReplicatedStorage.Save.OnServerEvent:Connect(function(plr, slot, text)
if plr:WaitForChild("leaderstats").Parts.Value <= 0 then warn("can't save "..plr.Name.." progress if they have no part") return end
save(plr, slot, text)
end)
game.ReplicatedStorage.Load.OnServerEvent:Connect(function(plr, slot)
load(plr, slot)
end)
game.ReplicatedStorage.Delete.OnServerEvent:Connect(function(plr, slot)
autoSavingStore:RemoveAsync(tostring(plr.UserId).." -slot"..tostring(slot))
end)