-- DOORS-style Camera Bob + Sprint FOV
-- LocalScript -> StarterPlayer -> StarterPlayerScripts
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local player = Players.LocalPlayer
local RUN_SPEED = 24
local WALK_BOB_SPEED = 8
local RUN_BOB_SPEED = 12
local WALK_BOB_AMOUNT = 0.08
local RUN_BOB_AMOUNT = 0.14
local SIDE_AMOUNT = 0.035
local TILT_AMOUNT = 0.025
local SMOOTHNESS = 10
-- FOV settings
local NORMAL_FOV = 70
local SPRINT_FOV = 76
local FOV_SMOOTHNESS = 6
local character
local humanoid
local currentBob = Vector3.zero
local currentTilt = 0
local time = 0
local function setupCharacter(char)
character = char
humanoid = char:WaitForChild("Humanoid")
end
if player.Character then
setupCharacter(player.Character)
end
player.CharacterAdded:Connect(setupCharacter)
RunService:BindToRenderStep(
"DoorsCameraEffects",
Enum.RenderPriority.Camera.Value + 1,
function(deltaTime)
local camera = workspace.CurrentCamera
if not character or not humanoid or humanoid.Health <= 0 then
return
end
local velocity = humanoid.RootPart
and Vector3.new(
humanoid.RootPart.AssemblyLinearVelocity.X,
0,
humanoid.RootPart.AssemblyLinearVelocity.Z
).Magnitude
or 0
local moving = velocity > 1
local sprinting = velocity >= RUN_SPEED - 2
local bobSpeed
local bobAmount
if sprinting then
bobSpeed = RUN_BOB_SPEED
bobAmount = RUN_BOB_AMOUNT
else
bobSpeed = WALK_BOB_SPEED
bobAmount = WALK_BOB_AMOUNT
end
-- Camera bob
if moving then
time += deltaTime * bobSpeed
local y = math.sin(time * 2) * bobAmount
local x = math.cos(time) * SIDE_AMOUNT
local tilt = math.sin(time) * TILT_AMOUNT
local targetBob = Vector3.new(x, y, 0)
currentBob = currentBob:Lerp(
targetBob,
math.clamp(deltaTime * SMOOTHNESS, 0, 1)
)
currentTilt += (tilt - currentTilt)
* math.clamp(deltaTime * SMOOTHNESS, 0, 1)
else
currentBob = currentBob:Lerp(
Vector3.zero,
math.clamp(deltaTime * SMOOTHNESS, 0, 1)
)
currentTilt += (0 - currentTilt)
* math.clamp(deltaTime * SMOOTHNESS, 0, 1)
end
-- Sprint FOV
local targetFOV = sprinting and SPRINT_FOV or NORMAL_FOV
camera.FieldOfView +=
(targetFOV - camera.FieldOfView)
* math.clamp(deltaTime * FOV_SMOOTHNESS, 0, 1)
camera.CFrame =
camera.CFrame
* CFrame.new(currentBob)
* CFrame.Angles(0, 0, currentTilt)
end
)