How to reset rotation of cframe except for y axis

How to reset rotation of CFrame except for a particular axis? I looked at this post but am still stuck.

Thanks for your time.

part.CFrame = part.CFrame * CFrame.Angles(0, 0, 0) -- Swap out for whatever you want to keep

Or you don’t even need to use CFrame

part.Orientation =, part.Orientation.Y, 0) -- Swap Y for whatever you want to keep

I need to use cframe as im using setting cframe of a bodygyro. So i need to get the cframe of a part, then only change it on the y axis like this:

local part.CFrame = part.CFrame * CFrame.Angles(0, y-angle, 0)

however the issue with this is, when the part.cframe changes its x and z values from bumping into things and naturally rotating in the physical world, it saves into part.CFrame (as this command is run every runservice.heartbeat)

part.CFrame = part.CFrame * CFrame.Angles(part.Orientation.X, new y angle, part.Orientation.Z)


local RotationX, RotationY, RotationZ = OldCFrame:ToOrientation()

local NewCFrame = * CFrame.Angles(0, RotationY, 0)

Step 1: Get the rotation of the CFrame (note it’s stored in radians and not degrees, use math.deg() to convert to degrees).

Step 2: Create a new CFrame at the old CFrame’s position and multiply it with the old CFrame’s Y rotation. The new CFrame is effectively the old one but without it’s rotation except for the Y axis.


Better yet, just don’t use angular space.

local fwd = -part.CFrame.LookVector *,0,1)
local up = part.CFrame.UpVector
local right = fwd:Cross(up)
part.CFrame = CFrame.fromMatrix(part.Position, right, up, fwd)

This is unidiomatic. * CFrame.Angles() essentially does this calculation anyways. If you’re constructing a CFrame, there’s no reason to overcomplicate the code.

Its not over complicating, in fact its more efficient. Using .Angles uses trigonometric functions to convert the vector space of rotation matrices to angular space, but directly using vector space cuts out that step.

People over-use euler angles which cloud’s beginner’s understanding of CFrames