It sounds like you want the CFrame rotation without position. You can just subtract the position to do this:

local cf = someCFrame - someCFrame.Position

Further explanation:
Using CFrame.Angles simply constructs a rotated CFrame object at the point of origin (0, 0, 0). Thus, to get a CFrame with just its rotation, you need to translate it back to the point of origin. Thankfully, the actual position is available, so we just need to subtract its position to get it back at the point of origin.

As @Crazyman32 said, you likely just want to get the rotation component of the CFrame but if you really need to get the values that you would use in the CFrame.Angles constructor there is an API for that.

local cf = CFrame.Angles(math.pi/2, 0, 0)
local x, y, z = cf:ToEulerAnglesYXZ()
local newCF = CFrame.Angles(x, y, z)
-- newCF is aprox equal to cf, some loss of precision likely

The XYZ properties are always going to be the position coordinates, not rotation. The rotation is derived from the rest of the CFrame matrix.

I’m not very good with that stuff, but there’s a way to use some trig functions to reconstruct the rotational XYZ from the other CFrame components. However, I think that’s exactly what ToEulerAnglesYXZ() is doing.

if (input.UserInputType == Enum.UserInputType.MouseButton1) then
if (self.CanFire == false or self.FPS.IsSprinting) then return end
self.CanFire = false
self.Recoil.angularFrequency = 20
-- local x, y, z = Camera.CFrame:ToEulerAnglesYXZ()
-- local OriginalCameraAngle = Vector3.new(math.deg(x),math.deg(y),math.deg(z))
-- local sx, sy, sz, m00, m01, m02, m10, m11, m12, m20, m21, m22 = Camera.CFrame:GetComponents()
-- local x = math.atan2(-m12, m22)
-- local y = math.asin(m02)
-- local z = math.atan2(-m01, m00)
-- local OriginalCameraAngle = Vector3.new(y,z,0)
-- local Angle = Vector3.new(Camera.CFrame - Camera.CFrame.Position)
-- Angle = Vector3.new(math.deg(Angle.X), math.deg(Angle.Y), math.deg(Angle.Z))
local x, y, z = Camera.CFrame:ToEulerAnglesYXZ()
local Angle = Vector3.new(math.deg(x),math.deg(y),math.deg(z))
print(Angle)
if (self.FireType == "Auto") then
while (UserInputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton1)) do
self:Fire()
end
elseif (self.FireType == "Semi") then
self:Fire()
elseif (self.FireType == "Burst") then
self:Fire()
wait(.1)
self:Fire()
wait(.1)
self:Fire()
end
self.Recoil.angularFrequency = 10
self.Recoil.p = Angle
self.CanFire = true
end

Hmmm… what I am trying to do is have a gun, when it is done firing, return the camera to it’s original rotation.

First, make sure when you using math.rad(radius) when using CFrame.Angles(). Math.rad is basically a function that takes the a number and makes it to an angle. Using this, when you do something like

That is not what math.rad function does. rad takes an angle given in degrees, and converts it to an angle given in radians. It’s a simple conversion with the following formula:

function rad(x)
return x * math.pi / 180
end

Likewise, math.deg is its counterpart for converting angles given in radians to angles given in degrees.

You are trying to use a mathematical spring for rotational camera recoil. You are asking how to convert the spring to angles, but you should be asking how to interpolate a cframe with the spring code you have.

Speaking of which thats not particularly easy to do so i rcmd trying a different approach. I have a FPS guide somewhere on the devforum with an example placefile. That may help!

I’m not having a problem with the recoil. I need the gun to return to the original angle that was before the gun was fire, when the gun is done firing.

You could try running a for loop twice (first for recoil, second for recovery) or you could try repeatedly using Lerp() to take the camera where you want to go.

An example of lerp would be

local angle = 0.2
for i = 1,5 do
workspace.Camera.CFrame = workspace.Camera.CFrame:Lerp(workspace.Camera.CFrame * CFrame.Angles(angle,0,0), 0.05)
wait()
end
for i = 1,5 do -- return camera to original position
workspace.Camera.CFrame = workspace.Camera.CFrame:Lerp(workspace.Camera.CFrame * CFrame.Angles(-angle,0,0), 0.05)
wait()
end

or simply

for i = 1,5 do -- return camera to original position
workspace.Camera.CFrame = workspace.Camera.CFrame * CFrame.Angles(angle,0,0)
wait()
end
for i = 1,5 do -- return camera to original position
workspace.Camera.CFrame = workspace.Camera.CFrame * CFrame.Angles(-angle,0,0)
wait()
end

I know this is a very old post, and I found it actually just looking for a way to mirror a cframe’s roation around a single axis… however, after reading all the posts…

What would probably work is having 2 CFrames for the camera, one is the Actual camera cframe, and one is the Visual camera cframe

Visual is what you will see, actual is where the camera ‘should’ be looking.
Both of these CFrames get upated every time the mouse is moved
However for recoil, only the visible cframe is given a rotation around the x? to move the view upwards
Have the view cframe always trying to lerp its way back to the actual cframe

So that as you look around, even during recoil, you will still end up with the camera returning to where the player is more currently looking.

You could also add a way to ‘unhook’ the trying to sync up the view and actual cframes, so that you could have a sort of ‘look over your shoulders’ effect, for games that might have a more ‘fixed’ actual cframe

been melting my brain for the past 2 or so hours trying to understand how quaternion rotations work just to do what you just said. you are a true life saver g