Tilt camera smoothly according to change in mouse x position

  1. I am trying to make a glider camera, the player can move the mouse and the glider will turn left or right, like the glide minigame from minecraft legacy.

  2. I am unable to figure out how to implement smooth camera tilting with my current script. The pitch and yaw variables are calculated every frame but i don’t know how i can Lerp the camera tilt since the pitch and yaw change every frame.

  3. I tried storing a pitch in a variable outside the update loop but i don’t even know how I can calculate when i need to set the variable to 0, and when i need to set it to the current pitch.

In the end the camera should smoothly tilt left or right depending on the pitch (delta mouseX * rotationSpeed)

local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")

local player = Players.LocalPlayer
local camera = workspace.CurrentCamera
local character = player.Character or player.CharacterAdded:Wait()
local humanoidRootPart = character:WaitForChild("HumanoidRootPart")

-- Camera configuration
local cameraDistance = 10 -- Distance from player
local verticalOffset = 3 -- Vertical offset from player
local rotationSpeed = 5 -- Speed of camera rotation (higher means more tilt)
local recenterSpeed = 0.08 -- Speed at which the camera recenters (higher is faster)

-- Variables to store mouse input
local mouseX, mouseY = 0, 0
local lastMouseInputTime = 0
local recenterDelay = 0.1 -- Delay before recentering (in seconds)
local tilt = 0

-- Function to update camera position and rotation
local humanoid_rotation = 0
local function updateCamera()
	-- Calculate target position
	local targetPosition = humanoidRootPart.CFrame.Position - humanoidRootPart.CFrame.LookVector * cameraDistance + Vector3.new(0, verticalOffset, 0)

	-- Calculate desired rotation based on mouse input
	local pitch = (mouseX * rotationSpeed)
	local yaw =   (mouseY * rotationSpeed)
	
	
	local mouseRotation = CFrame.Angles(0, 0, tilt)
	local currentRotation = (camera.CFrame - camera.CFrame.Position) -- Current camera rotation without position

	-- Calculate recentering towards default rotation
	local currentTime = tick()
	if currentTime - lastMouseInputTime > recenterDelay then
		local targetRotation = (humanoidRootPart.CFrame - humanoidRootPart.CFrame.Position)     -- Character's rotation
		--local targetRotation = (humanoidRootPart.CFrame - humanoidRootPart.CFrame.Position) * mouseRotation    -- tilt is stuttery
		-- will be applied to camera
		currentRotation = currentRotation:Lerp(targetRotation , recenterSpeed) 
	end
	
	-- Set the camera CFrame to target position with interpolated rotation
	camera.CFrame = CFrame.new(targetPosition) * currentRotation 
	
	-- rotate player model slightly to simulate tilt	
	if pitch > 0 then
		humanoid_rotation = .03
	elseif pitch < 0 then
		humanoid_rotation = -.03
	end
	-- apply tilt
	humanoidRootPart.CFrame = humanoidRootPart.CFrame * CFrame.Angles(0, humanoid_rotation, 0)
	
	mouseX, mouseY = 0,0 -- to prevent drifting
	humanoid_rotation = 0
end

-- Function to handle mouse movement
local function onMouseMove(input)
	if input.UserInputType == Enum.UserInputType.MouseMovement then
		mouseX = mouseX + input.Delta.X
		mouseY = mouseY + input.Delta.Y
	end
end

-- Connect input event to onMouseMove
UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
UserInputService.InputChanged:Connect(onMouseMove)

-- Update the camera every frame
RunService.RenderStepped:Connect(updateCamera)

RunService:BindToRenderStep("MouseLock",Enum.RenderPriority.Last.Value+1,function()
	UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
end)
2 Likes

Hey man, do you mind if i use this script? I need one like it for my game. I won’t use it if you’re not okay with it and sorry for necroposting.

yes you can yes you can yes you can yes you can yes you can yes you can yes you can yes you can yes you can yes you can yes you can yes you can yes you can