Hi everyone, I am trying to incorporate a head-bobbing script into a game of mine, but it isn’t working. I haven’t found any head-bobbing script that worked as intended.
I am using the following script, all credit is to BuiltToWreck and his Devforum tutorial “Configurable Head Bobbing Script”. I did put it in a local script under Starter Character Scripts, and I tried locking in first person though that didn’t work. I’m not asking in a comment under his tutorial because every head-bobbing script hasn’t worked for me, so I figure there’s something wrong with my implementation.
--[[
Created by @BuiltToWreck
Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)
https://creativecommons.org/licenses/by-sa/4.0/
You are free to:
- Share — copy and redistribute the material in any medium or format
- Adapt — remix, transform, and build upon the material
for any purpose, even commercially.
Under the following terms:
- Attribution — You must give appropriate credit, provide a link to the license,
and indicate if changes were made. You may do so in any reasonable manner, but
not in any way that suggests the licensor endorses you or your use.
- ShareAlike — If you remix, transform, or build upon the material, you must
your contributions under the same license as the original.
- No additional restrictions — You may not apply legal terms or technological
measures that legally restrict others from doing anything the license permits.
Place in StarterCharacterScripts
Adjust constants to your liking.
]]
-- CONSTANTS --
-- Camera position offset from HumanoidRootPart:
local OFFSET = Vector3.new(0, 3, 0)
-- Mouse sensitivity multiplier
local SENSITIVITY = 0.006
-- Verticle angle limits (how far you can look up and down):
local UPPER_ANGLE_LIMIT = math.rad(85)
local LOWER_ANGLE_LIMIT = math.rad(-85)
-- How many bobs per second horizontally and vertically:
local BOB_FREQUENCY_Y = 4
local BOB_FREQUENCY_X = 2
-- How intense the horizontal and vertical bobs are:
local BOB_AMPLITUDE_X = 0.6
local BOB_AMPLITUDE_Y = 0.4
-- The maximum velocity that affects the intensity of the bob:
local MAX_VELOCITY = 16
-- How fast it takes for bobbing to start/stop when you start/stop moving:
local RECENTER_SPEED = 4
-- SERVICES --
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local UserInputService = game:GetService("UserInputService")
-- REFERENCES --
local localPlayer = Players.LocalPlayer
local character = localPlayer.Character or localPlayer.CharacterAdded:Wait()
local currentCamera = workspace.CurrentCamera
-- VARIABLES --
local cameraAngle = Vector2.new(0, 0)
local currentTime = 0
local velocityMultiplier = 0
-- FUNCTIONS --
local function scalarLerp(a, b, c)
c = math.clamp(c, 0, 1)
return a + c * (b - a)
end
local function renderStepped(deltaTime)
local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
local mouseDelta = UserInputService:GetMouseDelta() * SENSITIVITY
-- Calculate bob offsets
currentTime += deltaTime
local bobOffsetY = (math.sin(currentTime * math.pi * BOB_FREQUENCY_Y) - 0.5) * BOB_AMPLITUDE_Y
local bobOffsetX = (math.sin(currentTime * math.pi * BOB_FREQUENCY_X) - 0.5) * BOB_AMPLITUDE_X
-- Smooth between bobbing and neutral based on horizontal velocity
local velocityMagnitude = (humanoidRootPart.Velocity * Vector3.new(1,0,1)).Magnitude
local targetVelocityMultiplier = math.clamp(velocityMagnitude, 0, MAX_VELOCITY) / MAX_VELOCITY
velocityMultiplier = scalarLerp(velocityMultiplier, targetVelocityMultiplier, RECENTER_SPEED * deltaTime)
bobOffsetX *= velocityMultiplier
bobOffsetY *= velocityMultiplier
-- Update the camera angle, clamp it to angle limits
cameraAngle -= mouseDelta
cameraAngle = Vector2.new(
cameraAngle.X,
math.clamp(cameraAngle.Y, LOWER_ANGLE_LIMIT, UPPER_ANGLE_LIMIT)
)
-- Set the cframe of the camera
currentCamera.CFrame =
CFrame.new(humanoidRootPart.Position + OFFSET + Vector3.new(0, bobOffsetY, 0)) *
CFrame.Angles(0, cameraAngle.X, 0) *
CFrame.Angles(cameraAngle.Y, 0, 0) *
CFrame.new(bobOffsetX, 0, 0)
end
-- LOGIC/SETUP/CONNECTIONS --
localPlayer.CharacterAppearanceLoaded:Wait()
currentCamera.CameraType = Enum.CameraType.Scriptable
UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
-- Make character invisible
for _, desc in ipairs(character:GetDescendants()) do
if desc:IsA("Part") then
desc.Transparency = 1
end
end
RunService.RenderStepped:Connect(renderStepped)