How to get the camera's CFrame without the up-down rotation

I’m making a game with a viewmodel and I need to move it to the camera’s position and rotation, but without the vertical rotation of the camera (so it stays in place as I look up and down). Currently I have this code, but it makes the viewmodel rotate in weird directions when I rotate the camera. Does anyone know how to achieve this?

local xc,yc,zc = cam.CFrame:ToEulerAnglesXYZ()
viewmodel.Root.CFrame = CFrame.new(cam.CFrame.Position) * CFrame.Angles(xc,0,zc)

Can you send a gif of what the rotation looks like?

your code should work, except CFrame.Angles expects radians when ToEulerAngles returns degrees, simply use math.rad

This function was given to me many years ago when I had a similar issue, and now I pass it along to you.

local function removePitch(cframe: CFrame): CFrame
	local xVector: Vector3 = cframe.XVector
	local yVector: Vector3 = Vector3.yAxis
	local zVector: Vector3 = xVector:Cross(yVector)
	return CFrame.fromMatrix(cframe.Position, xVector, yVector, zVector)
end

If I understood correctly, you want the model to only rotate in the XZ plane direction. This means rotation around y axis. So the angle you removed and the ones you left were the exact opposite of what you should have removed and left. This should work.

local xc,yc,zc = cam.CFrame:ToEulerAnglesXYZ()
viewmodel.Root.CFrame = CFrame.new(cam.CFrame.Position) * CFrame.Angles(0,yc,0)

The function @Rocky28447 gave works too, since the RightVector should stay the same (assuming it’s already parallel to the XZ plane) and you know the desired UpVector. These two vectors are enough information to calculate the last vector in the CFrame, the back vector.

Rocky’s function can be simplified because CFrame.fromMatrix can calculate the back vector given the other two rotation vectors so you don’t need to calculate the back vector yourself.

local function removePitch(cframe: CFrame): CFrame
	local xVector: Vector3 = cframe.RightVector
	local yVector: Vector3 = Vector3.yAxis
	return CFrame.FromMatrix(cframe.Position, xVector, yVector)
end
1 Like