Saving models to datastore corrupts rotation

Im making a building game but i ran into a problem where saving a model rotation went wrong

The issue is that when i load it the rotation is different than saved

the saving/loading script -

local datastore = game:GetService("DataStoreService")
local PltData
local plrs = nil
local savingtable = {}
local Parts = {}
local Bound = {}
local CooldDown = true
function getCorners(part)	
	local cf = part.CFrame
	local size = part.Size

	local corners = {}


	local frontFaceCenter = (cf + cf.LookVector * size.Z/2)
	local backFaceCenter = (cf - cf.LookVector * size.Z/2)

	local topFrontEdgeCenter = frontFaceCenter + frontFaceCenter.UpVector * size.Y/2
	local bottomFrontEdgeCenter = frontFaceCenter - frontFaceCenter.UpVector * size.Y/2
	local topBackEdgeCenter = backFaceCenter + backFaceCenter.UpVector * size.Y/2
	local bottomBackEdgeCenter = backFaceCenter - backFaceCenter.UpVector * size.Y/2

	corners.topFrontRight = (topFrontEdgeCenter + topFrontEdgeCenter.RightVector * size.X/2).Position
	corners.topFrontLeft = (topFrontEdgeCenter - topFrontEdgeCenter.RightVector * size.X/2).Position

	corners.bottomFrontRight = (bottomFrontEdgeCenter + bottomFrontEdgeCenter.RightVector * size.X/2).Position
	corners.bottomFrontLeft = (bottomFrontEdgeCenter - bottomFrontEdgeCenter.RightVector * size.X/2).Position

	corners.topBackRight = (topBackEdgeCenter + topBackEdgeCenter.RightVector * size.X/2).Position
	corners.topBackLeft = (topBackEdgeCenter - topBackEdgeCenter.RightVector * size.X/2).Position

	corners.bottomBackRight = (bottomBackEdgeCenter + bottomBackEdgeCenter.RightVector * size.X/2).Position
	corners.bottomBackLeft = (bottomBackEdgeCenter - bottomBackEdgeCenter.RightVector * size.X/2).Position

	return corners
end

function Loading(player)
	local plr
	plr = player
	local data
	local succes,errormsg = pcall(function()
		data = PltData:GetAsync(plr.UserId)
	end)
	if CooldDown then
		local succes,errormsg = pcall(function()
			data = PltData:GetAsync(plr.UserId)
		end)
		if succes and data ~= nil then
			for i,v in pairs(workspace.Plots:WaitForChild(plr.Name).content:GetChildren()) do
				v:Destroy()
			end
			for i,v in pairs(data) do
				local inst = data[i]
				if inst["Sort"] == "Part" then
					local part = Instance.new("Part")
					part.Parent = game.Workspace.Plots:WaitForChild(plr.Name).content
					part.Anchored = true
					part.CFrame = game.Workspace.Plots:WaitForChild(plr.Name).CFrame:ToWorldSpace(CFrame.new(Vector3.new(inst["PosXr"],inst["PosYr"],inst["PosZr"])))
					part.Rotation = Vector3.new(inst["RotX"],inst["RotY"],inst["RotZ"])
					part.Size = Vector3.new(inst["SizeX"],inst["SizeY"],inst["SizeZ"])
					part.Color = Color3.fromRGB(inst["ColorR"]*225,inst["ColorG"]*255,inst["ColorB"]*255)
					part.Material = inst["Material"]
					part.CanCollide = inst["CanCollide"]
					part.Transparency = inst["Transparency"]
					part.Reflectance = inst["Reflectance"]
					part.TopSurface = Enum.SurfaceType.Smooth
					part.BackSurface = Enum.SurfaceType.Smooth
					part.RightSurface = Enum.SurfaceType.Smooth
					part.LeftSurface = Enum.SurfaceType.Smooth
					part.BottomSurface = Enum.SurfaceType.Smooth
					part.FrontSurface = Enum.SurfaceType.Smooth
					local Shape = inst["Shape"]:sub(15, -1)
					part.Shape = Enum.PartType[Shape]
				elseif inst["Sort"] == "Model" then
					local part = game.ReplicatedStorage.Objects[inst["Name"]]:Clone()
					part.Parent = game.Workspace.Plots:WaitForChild(plr.Name).content
					part:SetPrimaryPartCFrame(game.Workspace.Plots:WaitForChild(plr.Name).CFrame:ToWorldSpace(CFrame.new(Vector3.new(inst["PosXr"],inst["PosYr"],inst["PosZr"]))) * CFrame.Angles(inst["RotX"],inst["RotY"],inst["RotZ"]))
				elseif inst["Sort"] == "Wedge" then
						local part = Instance.new("WedgePart")
						part.Parent = game.Workspace.Plots:WaitForChild(plr.Name).content
						part.Anchored = true
						part.CFrame = game.Workspace.Plots:WaitForChild(plr.Name).CFrame:ToWorldSpace(CFrame.new(Vector3.new(inst["PosXr"],inst["PosYr"],inst["PosZr"])))
						part.Rotation = Vector3.new(inst["RotX"],inst["RotY"],inst["RotZ"])
						part.Size = Vector3.new(inst["SizeX"],inst["SizeY"],inst["SizeZ"])
						part.Color = Color3.fromRGB(inst["ColorR"]*225,inst["ColorG"]*255,inst["ColorB"]*255)
						part.Material = inst["Material"]
						part.CanCollide = inst["CanCollide"]
						part.Transparency = inst["Transparency"]
						part.Reflectance = inst["Reflectance"]
						part.TopSurface = Enum.SurfaceType.Smooth
						part.BackSurface = Enum.SurfaceType.Smooth
						part.RightSurface = Enum.SurfaceType.Smooth
						part.LeftSurface = Enum.SurfaceType.Smooth
						part.BottomSurface = Enum.SurfaceType.Smooth
						part.FrontSurface = Enum.SurfaceType.Smooth
				end
			end
		end
		spawn(function()
			CooldDown = false
			wait(5)
			CooldDown = true
		end)
		print("DONE DONE DONE DONE DONE DONE DONE DONE DONE LOADING")
		PltData = nil
	end
end




function Saving(player)
	if CooldDown then
		table.clear(savingtable)
		for i,v in pairs(game.Workspace.Plots:WaitForChild(player.Name).content:GetChildren()) do
			if v.ClassName == "Part" then
				local relative = game.Workspace.Plots:WaitForChild(player.Name).CFrame:ToObjectSpace(v.CFrame)
				local newtable = {PosXr = relative.Position.X,PosYr = relative.Position.Y,PosZr = relative.Position.Z,SizeX = v.Size.X,SizeY = v.Size.Y,SizeZ = v.Size.Z,ColorR = v.Color.R,ColorG = v.Color.G,ColorB = v.Color.B,Material = v.Material.Name,CanCollide = v.CanCollide,Transparency = v.Transparency,Reflectance = v.Reflectance,RotX = v.Rotation.X,RotY = v.Rotation.Y,RotZ = v.Rotation.Z,Sort = "Part",Shape = tostring(v.Shape)}
				table.insert(savingtable,newtable)
			elseif v.ClassName == "Model" then
				local relative = game.Workspace.Plots:WaitForChild(player.Name).CFrame:ToObjectSpace(v.PrimaryPart.CFrame)
				local newtable = {PosXr = relative.Position.X,PosYr = relative.Position.Y,PosZr = relative.Position.Z,RotX = v.PrimaryPart.Rotation.X,RotY = v.PrimaryPart.Rotation.Y,RotZ = v.PrimaryPart.Rotation.Z,Sort = "Model",Name = v.Name}
				table.insert(savingtable,newtable)
			elseif v.ClassName == "WedgePart" then
				local relative = game.Workspace.Plots:WaitForChild(player.Name).CFrame:ToObjectSpace(v.CFrame)
				local newtable = {PosXr = relative.Position.X,PosYr = relative.Position.Y,PosZr = relative.Position.Z,SizeX = v.Size.X,SizeY = v.Size.Y,SizeZ = v.Size.Z,ColorR = v.Color.R,ColorG = v.Color.G,ColorB = v.Color.B,Material = v.Material.Name,CanCollide = v.CanCollide,Transparency = v.Transparency,Reflectance = v.Reflectance,RotX = v.Rotation.X,RotY = v.Rotation.Y,RotZ = v.Rotation.Z,Sort = "Wedge"}
				table.insert(savingtable,newtable)
			end
		end
		PltData:SetAsync(player.UserId,savingtable)
		
		print("DONE DONE DONE DONE DONE DONE DONE DONE SAVING",savingtable)
		PltData = nil
		spawn(function()
			CooldDown = false
			wait(5)
			CooldDown = true
		end)
	end
end

function remove(player)
	game.Workspace.Plots:WaitForChild(player.Name):Destroy()
end

game.ReplicatedStorage.Save.OnServerEvent:Connect(function(plr,name)
	PltData = datastore:GetDataStore(name)
	Saving(plr)
end)
game.ReplicatedStorage.Load.OnServerEvent:Connect(function(plr,name)
	PltData = datastore:GetDataStore(name)
	Loading(plr)
end)

The rotation the model is in im saving:
image

The rotation it loaded in:
image

1 Like

In the loading script try using CFrame.fromOrientation and using math.rad to convert to radians.

3 Likes

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