Custom Camera Has Weird Tilting

I’m working on a custom fps camera module for one of my games (and the public), but we have an issue, when looking left or right, the camera can tilt.

I’ve tried changing the camera’s z angle to always be 0, but that is jittery and you can’t look up or down. Here is a video:

Code Snip:

        local Angle = CFrame.Angles(0,0,0)
		
		Mouse.Move:Connect(function()
			local Delta = Input:GetMouseDelta()
			local Movement = Vector3.new(Delta.X,Delta.Y,0)
			local NewAngle = Angle*CFrame.Angles(-math.rad(Movement.Y),-math.rad(Movement.X),0)
			Angle = NewAngle
			self.Delta = Movement
		end)
		
		Run.RenderStepped:Connect(function()
			Input.MouseBehavior = Enum.MouseBehavior.LockCenter
			self.CameraStepped()
			Camera.CFrame = CFrame.new(Head.Position)*Angle
		end)
2 Likes

I think what your experiencing is gimbal lock, try splitting up the CFrame.Angles; or if that doesnt work try CFrame:FromEulerAnglesYXZ()

1 Like

Unfortunately, neither of those worked. I’m still stuck with the weird tilting.

Try just breaking apart the problem, see if you can turn it left and right with just the X first, and then see if you can go up and down with just the Y

Those both passed with no tilting issues, not sure what to do next

I made this freecam script a while back for a small project I was making; maybe it can be of some use to you

local UserInputService = game:GetService("UserInputService")
local camera = workspace.CurrentCamera

for i = 1,10 do
	camera.CameraType = Enum.CameraType.Scriptable
	task.wait()
end

camera.CFrame = CFrame.lookAt(workspace.Baseplate.Position - workspace.Baseplate.CFrame.RightVector * 15 + Vector3.new(0,15,0), workspace.Baseplate.Position)

local Freecam = {}

local sensitivity = 1.5
local movementSpeed = 10
local currentAngle = Vector2.new()


UserInputService.InputBegan:Connect(function(input, gameProcessedEvent)
	if gameProcessedEvent then return end
	if input.UserInputType == Enum.UserInputType.MouseButton2 then
		UserInputService.MouseBehavior = Enum.MouseBehavior.LockCurrentPosition
	end
end)

UserInputService.InputEnded:Connect(function(input, gameProcessedEvent)
	if gameProcessedEvent then return end
	if input.UserInputType == Enum.UserInputType.MouseButton2 then
		UserInputService.MouseBehavior = Enum.MouseBehavior.Default
	end
end)

game:GetService("RunService").RenderStepped:Connect(function(deltaTime)
	
	local delta = UserInputService:GetMouseDelta()
	currentAngle = currentAngle + Vector2.new(delta.Y, delta.X) * sensitivity * deltaTime
	camera.CFrame = CFrame.new(camera.CFrame.Position) * CFrame.fromEulerAnglesYXZ(-currentAngle.X, -currentAngle.Y, 0)

	if UserInputService:IsKeyDown(Enum.KeyCode.W) then
		camera.CFrame = camera.CFrame + camera.CFrame.LookVector  * movementSpeed * deltaTime
	end
	if UserInputService:IsKeyDown(Enum.KeyCode.A) then
		camera.CFrame = camera.CFrame + camera.CFrame.RightVector * -movementSpeed * deltaTime
	end
	if UserInputService:IsKeyDown(Enum.KeyCode.S) then
		camera.CFrame = camera.CFrame + camera.CFrame.LookVector * -movementSpeed * deltaTime
	end
	if UserInputService:IsKeyDown(Enum.KeyCode.D) then
		camera.CFrame = camera.CFrame + camera.CFrame.RightVector * movementSpeed * deltaTime
	end

end)

return Freecam

1 Like

That worked! I switched over to the Vector2 thing and at the end I added the EulerAngles instead of changing them first. Not sure how to explain it lol.

1 Like

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