Help with Camera Bobbing Script

I’ve been working recently on a horror game, and right now im working on the gameplay. Something around 2 days ago i wrote a head bobbing script and until now i can’t figure out how to prevent the Camera from snapping into it’s position after the player stops or starts walking, here’s a video of the issue im having:

I’ve tried searching help on the internet or just figuring it myself, but it didn’t work, here’s the full script:
(Local Script inside a Module Script in Starter Gui)

repeat wait() until game.ContentProvider.RequestQueueSize == 0

local Module = require(script.Parent)

local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")

local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Camera = game.Workspace.CurrentCamera
local Mouse = Player:GetMouse()

local StartingAngles = CFrame.Angles(0, 0, 0)
local CamPos, TargetCamPos = Camera.CFrame.Position, Camera.CFrame.Position
local AngleX, TargetAngleX = 0, 0
local AngleY, TargetAngleY = 0, 0
local Sensivity = 0.6
local Smoothness = 0.05

function Bobbing()
	local Time = tick()
	
	local x = math.sin(Time * 10) * 0.78
	local y = math.sin(Time * 5) * 0.6
	
	return x, y
end

function Update()
	for _, v in pairs(Character:GetDescendants()) do
		if v:IsA("Part") or v:IsA("UnionOperation") or v:IsA("MeshPart") then
			v.Transparency = 1
			v.LocalTransparencyModifier = 1
		end
		
		if v:IsA("Accessory") or v:IsA("Hat") then
			v:FindFirstChild("Handle").LocalTransparencyModifier = 1
			v:FindFirstChild("Handle").CanCollide = false
		end
		
		if v.Name == "Animate" or v.Name == "Animator" then
			v:Destroy()
		end
	end
	
	Mouse.Icon = Module.MouseIcon
end

UserInputService.InputChanged:Connect(function(InputObject)
	if InputObject.UserInputType == Enum.UserInputType.MouseMovement then
		local Delta = Vector2.new(InputObject.Delta.X/Sensivity, InputObject.Delta.Y/Sensivity) * Smoothness
		
		local X = TargetAngleX - Delta.Y
		TargetAngleX = (X >= 80 and 80) or (X <= -80 and -80) or X
		TargetAngleY = (TargetAngleY - Delta.X) %360
	end
end)

RunService.RenderStepped:Connect(function()
	Update()
	
	if Module.Mouse == true then
		UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
	
		CamPos = CamPos + (TargetCamPos - CamPos) * 0.28
		AngleX = AngleX + (TargetAngleX - AngleX) * 0.35
	
		local Distance = TargetAngleY - AngleY 
		Distance = math.abs(Distance) > 180 and Distance - (Distance / math.abs(Distance)) * 360 or Distance 
		AngleY = (AngleY + Distance * 0.35) %360
		Camera.CameraType = Enum.CameraType.Scriptable
	
		Camera.CFrame = CFrame.new(Character.Head.Position)
			* CFrame.Angles(0, math.rad(AngleY), 0)
			* CFrame.Angles(math.rad(AngleX), 0, 0)
			* CFrame.new(0, 0.5, 0)
		
		Character.HumanoidRootPart.CFrame = CFrame.new(Character.HumanoidRootPart.Position) * CFrame.Angles(0, math.rad(AngleY), 0)
		Character.Humanoid.AutoRotate = false
	end
	
	if Character.Humanoid.MoveDirection.Magnitude >0 and Module.Bobbing == true then
		local x, y = Bobbing()
		
		Camera.CFrame = Camera.CFrame * CFrame.Angles(math.rad(x), math.rad(y), 0)
	else
		
	end
end)

This is the part about Bobbing:

function Bobbing()
	local Time = tick()
	
	local x = math.sin(Time * 10) * 0.78
	local y = math.sin(Time * 5) * 0.6
	
	return x, y
end

if Character.Humanoid.MoveDirection.Magnitude >0 and Module.Bobbing == true then
		local x, y = Bobbing()
		
		Camera.CFrame = Camera.CFrame * CFrame.Angles(math.rad(x), math.rad(y), 0)
	else
		
	end

Any help would be really appreciated!

Use Lerp to smooth it back into the og position

1 Like

How do i get the Camera’s Origin Position if it changes all the time?

You could try getting the position right before the bobbing stuff starts to happen.

1 Like