You can accomplish this by using UserInputService:GetMouseDelta().
I created a short script that works in StarterCharacterScripts as an example:
local runService = game:GetService("RunService")
local userInputService = game:GetService("UserInputService")
local char = game.Players.LocalPlayer.Character
local camera = workspace.CurrentCamera
camera.CameraType = Enum.CameraType.Scriptable
userInputService.MouseBehavior = Enum.MouseBehavior.LockCenter -- The behavior must be LockCenter for this to work
local defaultCamOffset = Vector3.new(3.25,2.25,7.5)
local angleX = 0
local angleY = 0
runService.RenderStepped:Connect(function()
local mousePosChange = userInputService:GetMouseDelta() -- How much the mouse's position has changed since the previous frame
angleX = angleX - mousePosChange.X -- Update the X angle by subtracting the mouse's change in X
angleY = math.clamp(angleY - mousePosChange.Y, -75, 75) -- Update the Y angle by subtracting the mouse's change in Y. Clamp it so it doesn't go too high or low
local cameraCFrame = CFrame.new(char.HumanoidRootPart.Position) * CFrame.Angles(0, math.rad(angleX), 0) * CFrame.Angles(math.rad(angleY), 0, 0) -- Apply the camera angles
local cameraFocus = cameraCFrame:PointToWorldSpace(Vector3.new(defaultCamOffset.X, defaultCamOffset.Y, -9999)) -- Get the position the camera should be looking at
camera.CFrame = CFrame.new(cameraCFrame:PointToWorldSpace(defaultCamOffset), cameraFocus) -- Apply the offset and make the camera look at the focus
end)
Let me know if you have any issues with it, or need any further clarification.