Is it possible to get just one angle from a CFrame?

Hey so I’m trying to make something imitate the camera of the player, I got it to follow the camera in the specific position of the camera with CFrame.Position, but I need to make it rotate from left to right following the camera rotation, the RY angle from CFrame.Angles, haven’t found any solution around the forums with this problem, any help please?

If you want to get the CFrame.Angles of a CFrame you can just call CFrame:ToEulerAnglesXYZ() on your CFrame and then index those angles (X,Y,Z).

Just a warning that usually it’s not a great idea to convert CFrame back-and-forth to and from angles. You have to deal with a bunch of issues like gimbal lock and angles wrapping around at +/-180 degrees. Its often (but not always) better to work with the rotation matrix directly.

What are you actually trying to do, precisely? There might be a better answer.

1 Like

Converting CFrames aren’t even helping me to achieve it anyways.

It’s for a custom shiftlock that should smoothen the way players face the direction of the camera, I tried to smoothe it with Align Orientation, the part I’m trying to convert CFrames with is the part that has the second attachment for it so the Player faces where the camera is looking at.

Align Orientation Axis Only is a bit messed up so I wasn’t able to restric the angle to left and right, so I’m trying to just convert the CFrames right now, do you have a better idea for it? I would really appreciate it if you do

So to clarify, you want the camera movement to work as normal, but you want the player to rotate smoothly to face where the camera is, but only on the X-Z plane?

Yeah that’s basically all I need to do

If you had an AlignOrientation with PrimaryAxisOnly, and the PrimaryAxis was facing in the +X direction (i.e. left-to-right), that doesn’t work?

If it’s just a visual affect you could also set the orientation to some % of the way towards the camera’s orientation each frame like

local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local root = character:WaitForChild("HumanoidRootPart")

local camera = workspace.CurrentCamera

local PERCENT = 0.05 -- change to affect speed
local UP = Vector3.new(0, 1, 0)
game:GetService("RunService").Stepped:Connect(function(t, dt)
	local right = UP:Cross(-camera.CFrame.LookVector)
	local target = CFrame.fromMatrix(root.Position, right, UP)
	root.CFrame = root.CFrame:Lerp(target, PERCENT)
end)

You could put that in e.g. StarterCharacterScripts.

Obviously since this sets CFrame it makes walking side-to-side and backwards a bit strange but I’ll leave that to you :slight_smile:

You could also use a BodyGyro with 0 MaxTorque on the X and Z axes:

local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local root = character:WaitForChild("HumanoidRootPart")

local camera = workspace.CurrentCamera

local bodyGyro = Instance.new("BodyGyro")
bodyGyro.Name = "BodyGyroCameraAlignment"
bodyGyro.MaxTorque = Vector3.new(0, 10000, 0)
bodyGyro.D = 50
bodyGyro.Parent = root

game:GetService("RunService").Stepped:Connect(function()
	local rot = camera.CFrame - camera.CFrame.Position
	bodyGyro.CFrame = CFrame.new(root.Position) * rot
end)

Thank you very much for sharing these scripts with me! I actually never thought of Lerp or BodyGyro before, I’m starting to script recently so it’s all confusing for me

And yeah, the PrimaryAxisOnly didn’t worked “well” I should say, it did work but if I somehow moved the camera to the front of the character it stays positioned on the front instead of turning back, don’t know if I explained myself there.