Make the camera "tilt" when moving the mouse and going back to normal when the mouse stop moving

Sorry if I didn’t explain it correctly, I don’t find words to say it but I’ve got this video that shows the thing I would like to achieve.

As you can see the camera “tilts” when i move my mouse and returns back when i don’t move my mouse anymore. I probably know I need to use the TweenService thing but I don’t know how.
Thanks.

2 Likes

While you could use TweenService, it isn’t entirely necessary. You’d have to define two variables for the X and Z axis (or Y if you prefer). On renderstep when you move your mouse, get the distance the mouse moved on the X and Z axis and make a formula that decides how hard your camera should tilt based on distance.

Also in the same renderstep function, you could make it constantly subtract from the X and Z axis to reset it. So if you’re not moving it’ll reset naturally.

There’re many ways to do this, this is how I’ve done it in the past though.

Oh alright. So I have to make 2 variables called x and y and then I do that formula and then where do I use that formula? Also I’m bad at scripting as you probably see ;-;. Thanks anyways!

1 Like

The formula would be applied to the X and Z variables to get a camera tilt effect. Could be literally anything.

For example, I made a tilt on my gun arms which can be applied to the camera:

tiltSens = .1
tiltY = 0
tiltX = 0

cam = workspace.CurrentCamera

rs = game['Run Service']

function lerp(a, b, c)
	return a + (b - a) * c
end

rs.RenderStepped:connect(function()
    local delta = uis:GetMouseDelta()
		
    local x,y = delta.Y/10,delta.X/10
		
    tiltX = lerp(tiltX,x,tiltSens)
    tiltY = lerp(tiltY,y,tiltSens)

    local x,y,z = cam.CFrame:ToOrientation()

    cam.CFrame = CFrame.new(cam.CFrame.Position)*CFrame.Angles(math.deg(tiltX),y,math.deg(tiltZ))
end)

I haven’t tried applying it to a camera yet so it’s trial and error.

1 Like

Ohh alright, I’ll try to use it with the camera then. Thank youu so much tho! Ima mark it as a solution.

last thing, everything works but I don’t know how I can fix the thing that when I look in the Y coordinates (up or down) that does the tilt thing and goes back up. I would just want it to the X coordinates then (left or right), everything else seems to work properly.

Change this:

cam.CFrame = CFrame.new(cam.CFrame.Position)*CFrame.Angles(math.deg(tiltX),y,math.deg(tiltZ))

To this:

cam.CFrame = CFrame.new(cam.CFrame.Position)*CFrame.Angles(math.deg(tiltX)+x,y,math.deg(tiltZ)+z)

It doesn’t work if I leave it with “tiltZ” but when i put “tiltY” (i assume) it always keeps doing that it keep getting stuck there.

Thats a typo on my end, I put tiltZ but it should’ve been tiltY. However, the reason it gets stuck is because theres no subtraction of the tilt in the script provided. That is pretty much up to your likings. In the script where it loops RenderStepped, put something like:

if math.abs(tiltX) > 0 then
    tiltX= lerp(tiltX,0,.1)
end

if math.abs(tiltY) > 0 then
    tiltY = lerp(tiltY,0,.1)
end
3 Likes

Ohhh alright now it works. Thank you for your helping

this is extremely broken up and down doesnt work the sens is extremely high and the character is locked and i have no idea whats happening was it an update?

3 Likes

Correct, the solution dosen’t work. I have no idea. Please respond to this issue.

the script works just remove all the math.degs

Use math.rad()? Or just use the tilts bye themselfs?

it just works itself i think but you can try using math.rad too.

can you send the script i have no idea what to delete

Please let me know what I have done wrong here.

tiltSens = .1
tiltY = 0
tiltX = 0

cam = workspace.CurrentCamera

uis = game:GetService("UserInputService")
rs = game['Run Service']

function lerp(a, b, c)
	return a + (b - a) * c
end

rs.RenderStepped:connect(function()
	local delta = uis:GetMouseDelta()

	local x,y = delta.Y/10,delta.X/10

	tiltX = lerp(tiltX,x,tiltSens)
	tiltY = lerp(tiltY,y,tiltSens)
	
	
	if math.abs(tiltX) > 0 then
		tiltX= lerp(tiltX,0,.1)
	end

	if math.abs(tiltY) > 0 then
		tiltY = lerp(tiltY,0,.1)
	end
	
	
	
	local x,y,z = cam.CFrame:ToOrientation()

	cam.CFrame = CFrame.new(cam.CFrame.Position)*CFrame.Angles(tiltX+x,y,tiltY+z)
end)
1 Like
    local delta = UIS:GetMouseDelta()

	local x = -delta.X
	local y = -delta.Y

	tiltZ = lerp(tiltZ,x,tiltSens)
	
	cam.CFrame = cam.CFrame*CFrame.Angles(0, 0, tiltZ)
	
	if math.abs(tiltZ) > 0 then
		tiltZ = lerp(tiltZ, 0, 0.1)
	end
3 Likes

Put it in StarterCharacterScripts

---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- 
					-- StarterCharacterScripts -- 					
--	--	--	--	--	--	--	--	--	--	--	--	--	--	--	--	--	--	--
--	Place this into StarterCharacterScripts							--
--	CREDIT																--
--	WhoBloxxedWho; for the initial script								--
--	DoogleFox; some stuff ripped from his panner script					--
--	DuruTeru; shoving it all into this script and then some :)			--
--	Pupermuper; he added tilt
--																		--
--	UPDATE: turned it into r15, made it so you can swim right in water	--
--  Jan 07, 2017														--
--  UPDATE: added walkspeed easing directionally, also adding running   --	
--  Nov 13, 2020														--
--	--	--	--	--	--	--	--	--	--	--	--	--	--	--	--	--	--	--


---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- 


repeat wait() until game:GetService("Players").LocalPlayer.Character ~= nil
local runService = game:GetService("RunService")
local input = game:GetService("UserInputService")
local players = game:GetService("Players")

-- you can mess with these settings
CanToggleMouse = {allowed = true; activationkey = Enum.KeyCode.F;} -- lets you move your mouse around in firstperson
CanViewBody = true 		-- whether you see your body
Sensitivity = 0.4		-- anything higher would make looking up and down harder; recommend anything between 0~1
Smoothness = 0.10		-- recommend anything between 0~1
FieldOfView = 80		-- fov
TiltSpeed = 0.5 		-- recommend anything between 0~5 (normal value = 0.5)
MaximumTilt = 80		-- between 0-90
EnabledTilt = true		-- enable tilt
HeadOffset = CFrame.new(0,0.7,-0.7) -- how far your camera is from your head

-- you can mess with these settings
local easingtime = 1 --0~1
local walkspeeds = {
	enabled =		  false; --Enable running
	walkingspeed =		16;
	backwardsspeed =	10;
	sidewaysspeed =		15;
	diagonalspeed =		16;
	runningspeed =		25;
	runningFOV=			85;
}

local cam = game.Workspace.CurrentCamera
local player = players.LocalPlayer
local m = player:GetMouse()
m.Icon = "http://www.roblox.com/asset/?id=569021388" -- replaces mouse icon
local character = player.Character or player.CharacterAdded:wait()
local human = character.Humanoid
local humanoidpart = character.HumanoidRootPart

workspace.CurrentCamera.CameraType = Enum.CameraType.Scriptable

local head = character:WaitForChild("Head")
local CamPos,TargetCamPos = cam.CoordinateFrame.p,cam.CoordinateFrame.p 
local AngleX,TargetAngleX = 0,0
local AngleY,TargetAngleY = 0,0
local previousSineX = 0
local previousSineY = 0
TiltSpeed *= 0.01

local running = true
local freemouse = false
local defFOV = FieldOfView
local MouseMove = false
local MouseStuff = 0
local Tilt = 0

local w, a, s, d, lshift = false, false, false, false, false
 
--Script--
--------------------------------VIEW BODY--------------------------------

function updatechar()
	
	for _, v in pairs(character:GetChildren())do
		if CanViewBody == true then
			if v.Name == 'Head' then
				v.LocalTransparencyModifier = 1
				v.CanCollide = false
				v.face.LocalTransparencyModifier = 1
			end
		else
			if v:IsA'Part' or v:IsA'UnionOperation' or v:IsA'MeshPart' then
				v.LocalTransparencyModifier = 1
				v.CanCollide = false
			end
		end
		if v:IsA'Accessory' then
			v:FindFirstChild('Handle').LocalTransparencyModifier = 1
			v:FindFirstChild('Handle').CanCollide = false
		end
		if v:IsA'Hat' then
			v:FindFirstChild('Handle').LocalTransparencyModifier = 1
			v:FindFirstChild('Handle').CanCollide = false
		end

	end
	
end

-- math, thx roblox wiki
function lerp(a, b, t)
	return a * (1-t) + (b*t)
end

--------------------------------MOUSE-------------------------------- 

input.InputChanged:connect(function(inputObject)
	
	if inputObject.UserInputType == Enum.UserInputType.MouseMovement then
		MouseMove = true -- don't really work
		MouseStuff = inputObject
	end	
	
end)

--------------------------------KEYBOARD STUFF-------------------------------- 

input.InputBegan:connect(function(inputObject)
	
	if inputObject.UserInputType == Enum.UserInputType.Keyboard then
		if inputObject.KeyCode == CanToggleMouse.activationkey then
			if CanToggleMouse.allowed and freemouse == false then
				freemouse = true
			else
				freemouse = false
			end
		end
	end
	
	if inputObject.UserInputType == Enum.UserInputType.Keyboard then
		if inputObject.KeyCode == Enum.KeyCode.W then
			w = true
		end
		
		if inputObject.KeyCode == Enum.KeyCode.A then
			a = true
		end
		
		if inputObject.KeyCode == Enum.KeyCode.S then
			s = true
		end
		
		if inputObject.KeyCode == Enum.KeyCode.D then
			d = true
		end
		
		if inputObject.KeyCode == Enum.KeyCode.LeftShift then
			lshift = true
		end
	end
end)

input.InputEnded:connect(function(inputObject)
	if inputObject.UserInputType == Enum.UserInputType.Keyboard then
		if inputObject.KeyCode == Enum.KeyCode.W then
			w = false
		end
		
		if inputObject.KeyCode == Enum.KeyCode.A then
			a = false
		end
		
		if inputObject.KeyCode == Enum.KeyCode.S then
			s = false
		end
		
		if inputObject.KeyCode == Enum.KeyCode.D then
			d = false
		end
		
		if inputObject.KeyCode == Enum.KeyCode.LeftShift then
			lshift = false
		end
	end
end)

--------------------------------SCIPT THAT RUNS ON EVERY FRAME--------------------------------  

runService.RenderStepped:connect(function()
	--------------------------------MOUSE SCRIPT--------------------------------
	if EnabledTilt == true then
		if MouseMove == true then
			local delta = Vector2.new(MouseStuff.Delta.x/Sensitivity,MouseStuff.Delta.y/Sensitivity) * Smoothness
			local TiltX = MouseStuff.Delta.x
			local MaxTiltNew = MaximumTilt*0.01

			Tilt = math.clamp(lerp(Tilt, TiltX * TiltSpeed, 0.1), -MaxTiltNew, MaxTiltNew)

			local sineCFrame = math.sin(TiltX * Sensitivity)
			local lerpedSineX = lerp(previousSineX, sineCFrame, 0.1)
			local lerpedSineY = lerp(previousSineY, sineCFrame, 0.1)
			cam.CFrame *= CFrame.Angles(0, 0, -Tilt) * CFrame.new(0, lerpedSineY * 1, 0)


			local X = TargetAngleX - delta.y 
			TargetAngleX = (X >= 80 and 80) or (X <= -80 and -80) or X 
			TargetAngleY = (TargetAngleY - delta.x) %360

			previousSineX = lerpedSineX
			previousSineY = lerpedSineY
		end
	end
	
	--------------------------------RUNNING--------------------------------
	
	if running then
		updatechar()
		
		CamPos = CamPos + (TargetCamPos - CamPos) *0.28 
		AngleX = AngleX + (TargetAngleX - AngleX) *0.35 
		local dist = TargetAngleY - AngleY 
		dist = math.abs(dist) > 180 and dist - (dist / math.abs(dist)) * 360 or dist 
		AngleY = (AngleY + dist *0.35) %360
		cam.CameraType = Enum.CameraType.Scriptable
		cam.CoordinateFrame = CFrame.new(head.Position) 
			
		* CFrame.Angles(0,math.rad(AngleY),0)
		* CFrame.Angles(math.rad(AngleX),0,Tilt)
		* HeadOffset-- offset
		
		humanoidpart.CFrame=CFrame.new(humanoidpart.Position)*CFrame.Angles(0,math.rad(AngleY),0)
		else game:GetService("UserInputService").MouseBehavior = Enum.MouseBehavior.Default
	end

	if (cam.Focus.p-cam.CoordinateFrame.p).magnitude < 1 then
		running = false
	else
		running = true
		if freemouse == true then
			game:GetService("UserInputService").MouseBehavior = Enum.MouseBehavior.Default
		else
			game:GetService("UserInputService").MouseBehavior = Enum.MouseBehavior.LockCenter
		end
	end
	
	if not CanToggleMouse.allowed then
		freemouse = false
	end
	
	cam.FieldOfView = FieldOfView
	
	if walkspeeds.enabled then
		if w and s then return end
		
		if w and not lshift then
			FieldOfView = lerp(FieldOfView, defFOV,easingtime)
			human.WalkSpeed = lerp(human.WalkSpeed,walkspeeds.walkingspeed,easingtime)
		elseif w and a then
			human.WalkSpeed = lerp(human.WalkSpeed,walkspeeds.diagonalspeed,easingtime)
		elseif w and d then
			human.WalkSpeed = lerp(human.WalkSpeed,walkspeeds.diagonalspeed,easingtime)
		elseif s then
			human.WalkSpeed = lerp(human.WalkSpeed,walkspeeds.backwardsspeed,easingtime)
		elseif s and a then
			human.WalkSpeed = lerp(human.WalkSpeed,walkspeeds.backwardsspeed - (walkspeeds.diagonalspeed - walkspeeds.backwardsspeed),easingtime)
		elseif s and d then
			human.WalkSpeed = lerp(human.WalkSpeed,walkspeeds.backwardsspeed - (walkspeeds.diagonalspeed - walkspeeds.backwardsspeed),easingtime)
		elseif d then
			human.WalkSpeed = lerp(human.WalkSpeed,walkspeeds.sidewaysspeed,easingtime)
		elseif a then
			human.WalkSpeed = lerp(human.WalkSpeed,walkspeeds.sidewaysspeed,easingtime)
		end	
		
		if lshift and w then
			FieldOfView = lerp(FieldOfView, walkspeeds.runningFOV,easingtime)
			human.WalkSpeed = lerp(human.WalkSpeed,human.WalkSpeed + (walkspeeds.runningspeed - human.WalkSpeed),easingtime)
		end
	end
		
end)

---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- 

Report me any errors

5 Likes

@Puper_Muper
The script is working flawlessly.
But I can see one problem. When I move backwards, the camera glitches.
(also not working on mobile)
Here the clip. Do you have a fix to it
https://gyazo.com/2d05e318a4f99cdf0bc87888ef37f237

1 Like