How to add tilt controls to Freecam?

Hey there!
I’m currently trying to add the ability to tilt the camera in Freecam, so basically turning the camera sideways with set controls.

I’m not very advanced in ROBLOX Lua, but this is a feature that I have been wanting to add to my experience.

I’ve already tried searching the DevForum for similar posts where people are trying to achieve the same thing. It wasn’t successful. The Developer Hub doesn’t cover the specific topic that I am trying to do, so I’m left with no solution.

What I’m trying to understand is where and how I should approach this, as well as the steps I need to take in order to achieve my goal?

Thanks in advance!

2 Likes

Are you having issues tilting with the current mouse controls? Im confused what you want to achieve that isn’t available right now through the Freecam… when I use the cam I can completely swivel around, zoom in and out, and go forward back or sideways.

Ohhhh you mean tilt it so that the horizon isnt horizontal anymore?

Maybe you can change the CFrame.Rotation of your camera if … happen ! :wink:
I hope that was helpful ! :grinning:

Maybe use user input service to change the angle of the camera.

So basically, what I’m trying to achieve is the ability to use set key binds that tilt the camera left and right.

In the below screenshot, the part represents the entire camera. The orange face represents the camera PoV. The orange arrow represents the direction in which the camera is facing. When talking about tilt controls, I mean the ability for the camera to rotate on the red rotator (x-axis) with set key binds that provide left and right tilt control in Freecam.
Screen Shot 2022-05-06 at 13.27.43

I’ve seen some popular experiences feature this ability, with an example being Vehicle Simulator’s drone. It doesn’t have to necessarily be in Freecam, but something similar to what Freecam does.

You can declare a new rotation and set the values you do not want to change from previous one.

local currentOrientation = cam.Orientation -- 'cam' means your camera instance
cam.Orientation = Vector3.new(90, currentOrientation.Y, currentOrientation.Z) -- '90' it's a new turn on the X-axis, you have to change it to the needed one

Are you trying to do this on Mobile, where the user would have to touch their screen in a certain way, or on PC, whereas the user presses a key (such as Q or/and E?)

What about within Freecam, where it would continue rotate left until the “Z” key is let go or right until the “X” key is let go? Similar to how it works with going forwards and backwards in Freecam.

Does this need to be done in game or do you care if it is done in studio? If you dont care how to do it, use a cutscene… you can manipulate the camera any which way you want.

I want this to be done in-game.

Have you made any progress on the tilting of the camera? When does the camera tilt?

Try this:

local userInputService = game:GetService('UserInputService')

local cam = workspace.CurrentCamera -- You can assign a part if you have a camera fixed to it.

local right = 0
local left = 0
local sensitivity = 10 -- Degrees per second

userInputService.InputBegan:Connect(function(input, paused)
	if not paused then
		if input.KeyCode == Enum.KeyCode.Z then
			left = -1
		end
		if input.KeyCode == Enum.KeyCode.X then
			right = 1
		end
	end
end)

userInputService.InputEnded:Connect(function(input) -- We do not use 'paused' here to be able to cancel the movement even after the player has opened the chat.
	if input.KeyCode == Enum.KeyCode.Z then
		left = 0
	end
	if input.KeyCode == Enum.KeyCode.X then
		right = 0
	end
end)

while true do
	local dt = wait()
	local sum = left + right -- This is so as not to rotate the camera if you holding both buttons.
	local lastOrientation = cam.Orientation
	cam.Orientation = Vector3.new(lastOrientation.X + (dt * sum), lastOrientation.Y, lastOrientation.Z)
end

But if we use while loop then camera may not be smooth. You can use this instead while loop to make camera smooth but the rotation speed aslo will depend on the frame rate.

game:GetService('RunService').RenderStepped:Connect(function()
	local sum = left + right
	local lastOrientation = cam.Orientation
	cam.Orientation = Vector3.new(lastOrientation.X + sum, lastOrientation.Y, lastOrientation.Z)
end)

Of course, all this is designed for the local script.

Hi there! Thanks for the help with my issue. Unfortunately, when I tried running the script, it didn’t work.

Oh yeah. To get the rotation of the camera you need to use Camera.CFrame.Rotation and then convert radians with degrees using math.deg() and math.rad()

local lastCFrame = cam.CFrame
cam.CFrame = CFrame.new(lastCFrame.p) * CFrame.Angles(lastOrientation.X + math.rad(math.deg(lastOrientation.X) + (dt * sum)), lastOrientation.Y, lastOrientation.Z)

Hey there! For some reason, it still doesn’t work. Also, what does it mean by “paused” in terms of “userInputService.InputBegan:Connect(function(input, paused)” and "if not paused then"? Thanks again for helping me out!

This means that player is currently chatting or has opened the pause menu (button in the upper left corner or the esc key), etc.

Sometimes people naming it processed instead paused, but it was more logical to use paused.

Hey there! Thanks for clarifying that. Just to let you know, it still doesn’t work. I don’t think it is set to work when Freecam is activated. I tried adding to the code you provided, but I wasn’t successful.

Because all camera types updates every frame except Enum.CameraType.Scriptable.
You can script it for the movement using UserInputService and rotation using player’s mouse player:GetMouse().

Oh alright, I’ll try that. Thank you for helping me out!