Hi, there is a camera bobbing script i made that can help you (at least a bit) with your first person, or in general.
--CODED BY V1SIONUSE--
--STARTERCHARACTERSCRIPTS--
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local Player = Players.LocalPlayer
local Mouse = Player:GetMouse()
local Camera = workspace.CurrentCamera
local Humanoid = Player.Character:WaitForChild("Humanoid")
local bobbing = nil
local MAX_ZOOM_DISTANCE
if Player.Name == "V1SIONUSE" then
MAX_ZOOM_DISTANCE = 800
else
MAX_ZOOM_DISTANCE = 250
end
local MIN_ZOOM_DISTANCE = 0.5
-- Rest of your script here, using MAX_ZOOM_DISTANCE and MIN_ZOOM_DISTANCE as needed
-- Variables
local func1, func2, func3, func4 = 0, 0, 0, 0
local val, val2 = 0, 0
local int, int2 = 5, 5
local vect3 = Vector3.new()
-- Enable mouse icon
UserInputService.MouseIconEnabled = true
-- Function to perform linear interpolation
local function lerp(a, b, c)
return a + (b - a) * c
end
-- Function to update camera shake and movement
local function updateCamera(deltaTime)
deltaTime = deltaTime * 30
if Humanoid.Health <= 0 then
bobbing:Disconnect()
return
end
local rootMagnitude = Humanoid.RootPart and Vector3.new(Humanoid.RootPart.Velocity.X, 0, Humanoid.RootPart.Velocity.Z).Magnitude or 0
local calcRootMagnitude = math.min(rootMagnitude, 25)
if deltaTime > 1.5 then
func1, func2 = 0, 0
else
func1 = lerp(func1, math.cos(tick() * 0.5 * math.random(5, 7.5)) * (math.random(2.5, 10) / 100) * deltaTime, 0.05 * deltaTime)
func2 = lerp(func2, math.cos(tick() * 0.5 * math.random(2.5, 5)) * (math.random(1, 5) / 100) * deltaTime, 0.05 * deltaTime)
end
Camera.CFrame = Camera.CFrame *
(CFrame.fromEulerAnglesXYZ(0, 0, math.rad(func3)) *
CFrame.fromEulerAnglesXYZ(math.rad(func4 * deltaTime), math.rad(val * deltaTime), val2) *
CFrame.Angles(0, 0, math.rad(func4 * deltaTime * (calcRootMagnitude / 5))) *
CFrame.fromEulerAnglesXYZ(math.rad(func1), math.rad(func2), math.rad(func2 * 10)))
val2 = math.clamp(
lerp(val2, -Camera.CFrame:VectorToObjectSpace((Humanoid.RootPart and Humanoid.RootPart.Velocity or Vector3.new()) / math.max(Humanoid.WalkSpeed, 0.01)).X * 0.04, 0.1 * deltaTime),
-0.12,
0.1
)
func3 = lerp(func3, math.clamp(UserInputService:GetMouseDelta().X, -2.5, 2.5), 0.25 * deltaTime)
func4 = lerp(func4, math.sin(tick() * int) / 5 * math.min(1, int2 / 10), 0.25 * deltaTime)
if rootMagnitude > 1 then
val = lerp(val, math.cos(tick() * 0.5 * math.floor(int)) * (int / 200), 0.25 * deltaTime)
else
val = lerp(val, 0, 0.05 * deltaTime)
end
if rootMagnitude > 6 then
int = 10
int2 = 9
elseif rootMagnitude > 0.1 then
int = 6
int2 = 7
else
int2 = 0
end
Player.CameraMaxZoomDistance = MAX_ZOOM_DISTANCE
Player.CameraMinZoomDistance = MIN_ZOOM_DISTANCE
vect3 = lerp(vect3, Camera.CFrame.LookVector, 0.125 * deltaTime)
end
-- Connect the update function to RenderStepped for continuous updates
bobbing = RunService.RenderStepped:Connect(updateCamera)
here is how it behaves