How to Save CFrame's Angles?

I need help saving the angles of a cframe.
right now i’m just using lookvector to set the Cframes rotation but it doesn’t always work

The Problem
robloxapp-20210120-2314023.wmv (489.7 KB)

When its loaded the rotations go weird
probably because I’m using cframe look at

Load Code

	local Data = BuildSaveData:GetAsync(Plr.UserId.."-Slot"..tostring(Slot))
	if Data and #Data > 0 then
		print(Plr.Name.."Loaded "..tostring(#Data).." Blocks")
		for i = 1,#Data do
			
			if i > 500 then
				break
			end
			
			local ActualData = Data[i]
			local Name = ActualData[1]
			local Position = ActualData[2]
			local Rotation = ActualData[3]
			local RotDirection = Vector3.new(Rotation[1],Rotation[2],Rotation[3])
			local Pos = Vector3.new(Position[1],Position[2],Position[3]) + (Vector3.new(0, 10000,Index.Value*200) - Vector3.new(0,36,0))
			local Cf = CFrame.new(Pos,Pos+RotDirection)
			
			if Name and game.Lighting.Blocks:FindFirstChild(Name) then
				local Block = GetBlock(Name)
				Block.Parent = BuildModel
				Block:SetPrimaryPartCFrame(Cf)
				RunService.Heartbeat:Wait()
			elseif Name and Name ~= "Chassis" then
				if WarnDebug == true then
					warn(Plr.Name.." Tried to load"..Name)
				end
			end
			
			if Name and Name == "Chassis" and not BuildModel:FindFirstChild("Chassis") then
				local Block = game.Lighting.OtherBlocks:FindFirstChild("Chassis"):Clone()
				Block.Parent = BuildModel
				Block:SetPrimaryPartCFrame(Cf)
				Chassis = Block
			end
		end
	end

Save Code

			local BuildModel2
	
			if StoredBuildClones:FindFirstChild(Plr.Name) then
				BuildModel2 = StoredBuildClones:FindFirstChild(Plr.Name)
			else
				BuildModel2 = game.Workspace.Builds:FindFirstChild(Plr.Name) or BuildModel
			end
			
			if BuildModel2 then
				if Debug == true then
					print("Saving "..Plr.Name.."'s BuildModel"..". Saved "..tostring(#BuildModel2:GetChildren()).." Blocks" )
					elseif WarnDebug == true then
					warn("Failed Saving "..Plr.Name.."'s BuildModel")
				end
			end
			
			local int2 = 0
			repeat wait() int2 = int2 + 1 until BuildModel2 and #BuildModel2:GetChildren() > 1  or int2 > 20 do end
			
			local newValue = {}
			local Blocks = BuildModel2:GetChildren()
			for i = 1,#Blocks do
				if i > 500 then
					break
				end
				
				if game.Lighting.Blocks:FindFirstChild(Blocks[i].Name) or game.Lighting.OtherBlocks:FindFirstChild(Blocks[i].Name) then
					local Block = Blocks[i].PrimaryPart
					local MidPos = (Vector3.new(0, 10000,Index.Value*200) - Vector3.new(0,36,0))
					local DeltaPosition = (Block.Position-MidPos)
					local LookVector = Block.CFrame.LookVector
					table.insert(newValue,{Block.Parent.Name,{DeltaPosition.X,DeltaPosition.Y,DeltaPosition.Z},{LookVector.X,LookVector.Y,LookVector.Z}})
				end
			end
			
			local success, err = pcall(function()
				BuildSaveData:SetAsync(Plr.UserId.."-Slot"..tostring(Slot),newValue)
			end)
			
			if success then
				if Debug == true then
					print("Successfully Saved "..Plr.Name.."'s BuildModel"..". With "..tostring(#BuildModel2:GetChildren()).." Blocks")
				end
			else
				if Debug == true then
					print("Saving WasFailed. Error")
					warn(err)
				end
			end

Here’s a Part with its LookVector shown as a blue arrow.

image

You’re trying to encode its orientation as a single vector. But this doesn’t constrain the orientation to a single value:

image

It can be rotated any amount on its local Z axis and it will still have the same LookVector.

You need 2 vectors to unambiguously encode the orientation.

Here’s an illustration showing the LookVector and RightVector:

image

CFrame.new(position, lookat) (which is the same as CFrame.lookat) assumes that you want the roll aka local Z rotation to be 0. It’s like it’s “forgetting which way is up” when you don’t explicitly store it.

Instead of storing 2 vectors you can store the XYZ euler angles which is only 3 numbers, so it takes a bit less space.

1 Like
local cf= CFrame.new(Vector3.new(0,0,0))* CFrame.Angles(0,1,0)
local x,y,z= cf.CFrame:ToEulerAnglesXYZ()
---------return 0,1,0

or

local angle= workspace.Floor.Orientation----Vector3
-----------returns the angle in degrees
----ex: 0,90,0
1 Like