How to apply CFrame rotation only around Y axis

I’m trying to create a function that, when called, rotates the character to face the same direction that the camera is. And it works great. A little too great.

My problem is that I only want the rotation to be applied around the Y axis, so that if the camera is facing down towards the ground, the player’s character doesn’t fall face first into the ground.

I know that this can be done by doing some math to find the difference in angle between the rootPart’s lookVector and the camera’s and then using CFrame.Angles, but I was wondering if there was a way to do it with the current state of my code. Thanks in advance!

local function faceCharacterWithCamera()
	local root_part : BasePart = (current_character.PrimaryPart :: BasePart).AssemblyRootPart :: BasePart
	local current_cframe : CFrame = root_part.CFrame

	local offset_rotation : CFrame = current_camera.CFrame.Rotation * root_part.CFrame.Rotation:Inverse()
	local temp_cframe : CFrame = root_part.CFrame * offset_rotation --need to figure out how to only apply rotation around y axis
	
	root_part.CFrame = root_part.CFrame * offset_rotation
end

I don’t really get it. Can’t you just do CFrame.Angles(0,ry,0)?

If that’s not what you mean, then might I suggest doing

local rx, ry, rz = PreviousCFrame:ToEulerAnglesXYZ()

ry = ry + math.rad(180) --// Rotate around Y-axis

local NewCFrame = CFrame.new(PreviousCFrame.Position) * CFrame.Angles(rx,ry,rz)

Correct me if I did anything wrong, I wrote this out without doublechecking.

That would work great if I always just wanted to turn the character around. However, I want to make it so that it faces the direction of the camera, which might not always be 180 degrees around

You can make ry anything. I made it +180 here for an example. In your case, you would get the ry of the camera and set this as the ry of the HumanoidRootPart.

1 Like

Are you not able to just use CFrame.lookat and just use the character’s upvector?

1 Like

Not sure how I would do this. Could you elaborate?

I didn’t realize you used ToEulerAngles, I didn’t even realize that method existed so thank you. However, when I tested it, it seems to work about half of the time for some odd reason. Sometimes it’s off by 180 and other times it just seems to rotate it a random amount.

Edit: think it has to do with the fact that the range is from -pi/2 to pi/2 as opposed to 0 to 2pi.

Like, get a vector position 10k studs in front of the camera and just do

local camera = --get camera
local character = --get character

local camFocus = camera.CFrame * CFrame.new(0, 0, -10000) -- camera direction
local charPivot = character:GetPivot() 

character:PivotTo(charPivot, camFocus.Position, charPivot.UpVector)-- use upvector so character always stays upright

alternatively you can just use the y position of the character

camFocus = Vector3.new(camFocus.X, charPivot.Position.Y, camFocus.Z)
1 Like

I also didn’t know this method existed. Thanks for the idea. I think I’m going to try out the ToEulerAngles idea first, but if that doesn’t work I’ll try this one next.

1 Like