By creating a local script in StarterPlayerScripts, you can now have camera sway when you move your mouse, you will also have camera sway when you are not moving to apply a breathing effect.
Create a local script and paste it in StarterPlayerScripts. Hopefully this helps developers out.
--Services
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")
--constants
local PLAYER = Players.LocalPlayer
local CAMERA = workspace.CurrentCamera
local SX,SY = .05,.04 -- IDLE sway speed
local MXY = 0.0005 --center position
local SIN,PI_2 = math.sin,math.pi*2
local IDLE_LERP_SPEED = .01
--varibables
local ix,iy = 0,0
local lsx,lsy = SX,SY
local lx,ly = MXY,MXY
--variables
local turn = 0
local lerp = function(a, b, t) return a + (b - a) * t end
PLAYER.CameraMode = Enum.CameraMode.LockFirstPerson
RunService:BindToRenderStep("CameraSway", Enum.RenderPriority.Camera.Value + 1, function(deltaTime)
local MouseDelta = UserInputService:GetMouseDelta()
turn = lerp(turn, math.clamp(MouseDelta.X, -3, 3), (15 * deltaTime))
lsx=lerp(lsx,SX,IDLE_LERP_SPEED)
lx=lerp(lx,MXY,IDLE_LERP_SPEED)
lsy=lerp(lsy,SY,IDLE_LERP_SPEED)
ly=lerp(ly,MXY,IDLE_LERP_SPEED)
ix = (ix + lsx)%PI_2
iy = (iy + lsy)%PI_2
CAMERA.CFrame = CAMERA.CFrame * CFrame.Angles(0, 0, math.rad(turn)) *
CFrame.Angles(SIN(ix)*lx,SIN(iy)*ly,0)
end)
Updated Version, which also pauses a second before idle sway so the two sways are not interfering which each other.
--Services
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")
--constants
local PLAYER = Players.LocalPlayer
local CAMERA = workspace.CurrentCamera
local SX,SY = .05,.04 -- IDLE sway speed
local MXY = 0.0005 --center position
local SIN,PI_2 = math.sin,math.pi*2
local IDLE_LERP_SPEED = .01
--varibables
local ix,iy = 0,0
local lsx,lsy = SX,SY
local lx,ly = MXY,MXY
--variables
local turn = 0
local lastCFramePosition = nil
local lastMoveTick = tick()
local lerp = function(a, b, t) return a + (b - a) * t end
PLAYER.CameraMode = Enum.CameraMode.LockFirstPerson
RunService:BindToRenderStep("CameraSway", Enum.RenderPriority.Camera.Value + 1, function(deltaTime)
local MouseDelta = UserInputService:GetMouseDelta()
turn = lerp(turn, math.clamp(MouseDelta.X, -3, 3), (15 * deltaTime))
lsx=lerp(lsx,SX,IDLE_LERP_SPEED)
lx=lerp(lx,MXY,IDLE_LERP_SPEED)
lsy=lerp(lsy,SY,IDLE_LERP_SPEED)
ly=lerp(ly,MXY,IDLE_LERP_SPEED)
ix = (ix + lsx)%PI_2
iy = (iy + lsy)%PI_2
CAMERA.CFrame = CAMERA.CFrame * CFrame.Angles(0, 0, math.rad(turn))
if lastCFramePosition and (lastCFramePosition - CAMERA.CFrame.Position).magnitude > .01 then lastMoveTick = tick() end
if tick() - lastMoveTick > 1 then CAMERA.CFrame = CAMERA.CFrame * CFrame.Angles(SIN(ix)*lx,SIN(iy)*ly,0) end
lastCFramePosition = CAMERA.CFrame.Position
end)