How to reset a CFrames rotation on only one axis locally?


How exactly would one go about resetting the Blue camera’s Highlighted Red Axis to the Red Camera’s rotation without CFrame.lookAt and without already knowing the red cameras CFrame.

I am making a camera system, and the camera moves via World Oriented Rotation on the x axis, but the Y axis is the objects local rotation upwards.

uis.InputChanged:Connect(function(k)
	if k.UserInputType == Enum.UserInputType.MouseMovement then
		local cf = partcam.CFrame
		local angle = CFrame.Angles(0,math.rad(k.Delta.X),0)
		local rotcf = angle:ToObjectSpace(cf)
		partcam.CFrame = CFrame.fromMatrix(cf.Position,rotcf.XVector,rotcf.YVector,rotcf.ZVector)
		
		local angl = CFrame.Angles(math.rad(-k.Delta.Y),0,0)
		partcam.CFrame *= angl
		
		local newcf = CFrame.Angles(0,0,0):ToObjectSpace(partcam.CFrame)

		local zvector = newcf.ZVector
		local xvector = newcf.XVector
		
		game.Players.LocalPlayer.PlayerGui.ScreenGui.TextLabel.Text = tostring(xvector)
		game.Players.LocalPlayer.PlayerGui.ScreenGui.TextLabel.TextLabel.Text = tostring(zvector)
		
		cl.CFrame = CFrame.fromMatrix(cf.Position,newcf.XVector,Vector3.new(0,1,0),newcf.ZVector)
	end
end)

This is what I have right now, however the issue is that when you rotate your camera over 90 degrees upwards, it will rotate the reset axis camera 180 degrees to face backwards where I am looking.


The red ghost camera is the desired result, however the actual result is just the red camera but its facing backwards.

Hello there! So, you’re working on a camera system and you’re trying to reset the rotation of the blue camera on the red axis to match the red camera’s rotation. You’re using mouse movement to rotate the camera and you’re running into an issue where when you rotate your camera over 90 degrees upwards, it rotates the reset axis camera 180 degrees to face backwards.

Here’s a solution for you:

First, let’s define a function that calculates the desired rotation. In this function, we’ll get the current camera position and the desired position of the red camera. Then, we’ll calculate the angle between these two positions and use that angle to reset the rotation of the blue camera on the red axis.

Here’s the code:

local function GetDesiredRotation(currentPos, desiredPos)
local direction = (desiredPos - currentPos).unit
local angle = math.acos(direction.y)
if direction.x < 0 then
angle = 2 * math.pi - angle
end
return angle
end

Next, let’s use this function in the InputChanged event to reset the rotation of the blue camera. We’ll first get the current position of the blue camera and the desired position of the red camera. Then, we’ll call the GetDesiredRotation function to get the desired rotation and use that to reset the rotation of the blue camera on the red axis.

Here’s the updated code:

uis.InputChanged:Connect(function(k)
if k.UserInputType == Enum.UserInputType.MouseMovement then
local cf = partcam.CFrame
local angle = CFrame.Angles(0,math.rad(k.Delta.X),0)
local rotcf = angle:ToObjectSpace(cf)
partcam.CFrame = CFrame.fromMatrix(cf.Position,rotcf.XVector,rotcf.YVector,rotcf.ZVector)
local angl = CFrame.Angles(math.rad(-k.Delta.Y),0,0)
	partcam.CFrame *= angl
	
	local currentPos = partcam.Position
	local desiredPos = redCamera.Position
	local desiredRotation = GetDesiredRotation(currentPos, desiredPos)
	
	partcam.CFrame = CFrame.new(currentPos) * CFrame.Angles(0, desiredRotation, 0)
end
end)

That’s it! This should solve the issue you’re facing and reset the rotation of the blue camera on the red axis to match the red camera’s rotation.

2 Likes

I appreciate your help, however in this scenario the red ghost camera doesn’t actually exist it’s there just to show you the desired result. What I’m looking for is something much like the Orientation of the CFrame, but it doesn’t lock at 90 degrees.

Basically I want to get the local rotation of the part.

Ok, So you want to find the local rotation of a part, but it shouldn’t be locked at 90 degrees. In that case, you can use the CFrame method toEulerAnglesYXZ to get the rotation of the part as Euler angles. Here’s an example script:

local part = script.Parent
local rotation = part.CFrame:toEulerAnglesYXZ()
print(rotation)

This will give you the Euler angles for the part’s rotation in the form of a Vector3. You can access the individual angles using the properties x , y , and z of the Vector3. For example, rotation.y would give you the angle around the Y axis. I hope this helps you!

I figured it out using :GetOrientation() and a hacky formula for what i needed.

I then constructed a CFrame using :FromOrientation(), with the Y value equaling 0.

If the angle was above 90 degrees, the Z value would be 180 instead of 0, so I just checked if it was 180 and reversed the remaining X value.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.