Orientation doesn't save in datastore

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)
3 Likes

Copy the CFrame by itself, everything else here is useless. CFrame is position + orientation. Ex:

r.CFrame = obj.CFrame

Done.

2 Likes

it didnt work and i got this error

also i tried to print the rotation data, it just printed “0, 0, 0” while the rotation was different


Last time when I was making my rocket game where you could build rocket and launch them I had the same problem to but I fixed it by doing Parts.Object.CFrame:GetComponents() and then for loading I simply put them all together

can you show me how to do that, i have no idea :sweat_smile:

xd. uhm what are you confused on

idk how do i get the values of it, i tried to split them but i failed

well as you can saw in the saving script I put the :GetComponents() in the uhm tables I guess {} and that will make the table looks like this and so you can just loops through all of the table

                [1] = -31.7697582244873,
                [2] = 35.27900314331055,
                [3] = -52.07206726074219,
                [4] = 1,
                [5] = 0,
                [6] = 0,
                [7] = 0,
                [8] = 1,
                [9] = 0,
                [10] = 0,
                [11] = 0,
                [12] = 1

the :GetComponents() function isnt a table and idk how to turn it into a table, can you help me and tell me how can i do that?

well just do {Part.CFrame:GetComponents())

Thank you so much, it worked!

Limit Limit Limit Limit

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.