What this script does (see video):
This script adjusts the field of view (FOV) of the camera based on the speed of the player’s character. The script uses a lerp function for a smooth transition between the current and target FOV values to create a more visually appealing effect. The FOV is continuously updated as the player moves, and if the character dies, the FOV is reset to the default value.
How to use:
Create a local script within StarterCharacterScripts.
Then paste the following code:
-- Roblox Lua script for controlling Field of View (FOV) based on player speed and zoom distance
-- Define variables
local player = game.Players.LocalPlayer
local humanoid, character
local RenderSteppedConnection = nil
local DiedConnection = nil
local AncestryChangedConnection = nil
local startFOV = 70 -- Initial FOV when not moving
local maxFOV = 90 -- Maximum FOV when moving at maximum speed
local startSpeed = 0 -- Initial speed
local maxSpeed = 100 -- Maximum speed
local fovSmoothness = 0.1 -- Smoothing factor for FOV transitions
local maxZoomDistance = 5 -- Maximum distance to zoom in
-- Linear interpolation function
-- The lerp function smoothly transitions between two values (Current FOV -> Target FOV) based on a specified parameter (fovSmoothness).
local function lerp(a, b, t)
return a + (b - a) * t
end
-- Function to calculate FOV based on speed and distance
local function calculateFOV(speed, distance)
local fov = startFOV + (speed / maxSpeed) * (maxFOV - startFOV)
if distance < maxZoomDistance then
local zoomFactor = 0.5 - (distance / maxZoomDistance)
fov = fov + zoomFactor * (maxFOV - fov)
fov = math.clamp(fov, startFOV, maxFOV) -- Clamp the FOV value between startFOV and maxFOV
end
return fov
end
-- Function to update FOV
local function updateFOV()
local camera = game.Workspace.CurrentCamera
if not camera or not character or not humanoid or not humanoid.Parent or not humanoid.RootPart or not humanoid.Parent:IsA("Model") or not humanoid.Parent:FindFirstChild("Head") or not character:FindFirstChild("Head") then
return -- Exit if essential objects are not valid
end
local distance = (camera.CFrame.Position - character.Head.Position).Magnitude
local speed = humanoid.RootPart.Velocity.magnitude
local targetFOV = calculateFOV(speed, distance)
local currentFOV = camera.FieldOfView
local smoothedFOV = lerp(currentFOV, targetFOV, fovSmoothness)
camera.FieldOfView = smoothedFOV -- Update the camera's FOV
end
local function handleCharacterRemoved()
if RenderSteppedConnection then
RenderSteppedConnection:Disconnect()
RenderSteppedConnection = nil
end
if DiedConnection then
DiedConnection:Disconnect()
DiedConnection = nil
end
if AncestryChangedConnection then
AncestryChangedConnection:Disconnect()
AncestryChangedConnection = nil
end
humanoid = nil -- Clear humanoid reference
character = nil -- Clear character reference
end
local function handleCharacterAdded(newCharacter)
character = newCharacter
humanoid = character:WaitForChild("Humanoid")
RenderSteppedConnection = game:GetService("RunService").RenderStepped:Connect(updateFOV)
DiedConnection = humanoid.Died:Connect(function()
game.Workspace.CurrentCamera.FieldOfView = startFOV
end)
AncestryChangedConnection = character.AncestryChanged:Connect(function(_, parent)
if parent == nil then
handleCharacterRemoved()
end
end)
end
-- Function to handle player character addition
local function onCharacterAdded(newCharacter)
handleCharacterAdded(newCharacter)
end
-- Function to handle player character removal
local function onCharacterRemoved(oldCharacter)
handleCharacterRemoved()
end
-- Connect event handlers for player character changes
player.CharacterAdded:Connect(onCharacterAdded)
player.CharacterRemoving:Connect(onCharacterRemoved)
-- Check for an existing character when the script starts
if player.Character then
onCharacterAdded(player.Character)
end
Credit or attribution not required. Feel free to use this in any project. And please share any improvements below