the first idea i had was to make a stationary point/attachment infront of the head and the gui would be updated constantly in a loop to that position. i know its a wacky solution but im not good with reading math head bob and yes i did took it from someone
-- CONSTANTS --
-- Camera position offset from HumanoidRootPart:
local OFFSET = Vector3.new(0, 3, 0)
local RAY_DISTANCE = 100
-- 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
local rad = math.rad
local Rot = CFrame.new()
local Tilt = CFrame.new()
-- VARIABLES --
local cameraAngle = Vector2.new(0, 0)
local currentTime = 0
local velocityMultiplier = 0
local MaxTilt = 85
-- FUNCTIONS --
local function GetRollAngle()
local Character = localPlayer.Character
if not Character then
return
end
local Cf = currentCamera.CFrame
return -Cf.RightVector:Dot(Character.Humanoid.MoveDirection)
end
local function scalarLerp(a, b, c)
c = math.clamp(c, 0, 1)
return a + c * (b - a)
end
function MouseRay(filterTable, filterType, mousePosition)
local rayData = currentCamera:ScreenPointToRay(mousePosition.X, mousePosition.Y, 0)
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = filterTable
raycastParams.FilterType = filterType
return workspace:Raycast(rayData.Origin, rayData.Direction * RAY_DISTANCE, raycastParams)
end
local function InitOffsetAttachment(Char)
local Attachment = Instance.new("Attachment")
Attachment.Name = "OFFSET"
Attachment.Parent = character:WaitForChild("HumanoidRootPart")
Attachment.WorldPosition = character:WaitForChild("Head").Position
return Attachment.Position
end
local function MakeBodyVisible(Char,Match)
for _,v in pairs(Char:GetDescendants()) do
if v:IsA("BasePart") then
v.LocalTransparencyModifier = 1
end
end
end
local function renderStepped(deltaTime)
local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
local mouseDelta = UserInputService:GetMouseDelta() * SENSITIVITY
local MouseDeltaX = UserInputService:GetMouseDelta().X
-- 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
local Roll = GetRollAngle() * 4
Rot = Rot:Lerp(CFrame.Angles(0, 0, rad(Roll)),0.075)
localPlayer.Character:WaitForChild("Humanoid").AutoRotate = false
local RootPos, MousePos = humanoidRootPart.Position, localPlayer:GetMouse().Hit.Position
humanoidRootPart.CFrame = CFrame.new(RootPos, Vector3.new(MousePos.X, RootPos.Y, MousePos.Z))-- Temp solution
Tilt = Tilt:Lerp(CFrame.Angles(0,0, rad(math.clamp(math.round(MouseDeltaX),-MaxTilt,MaxTilt)),0),0.075)
currentCamera.CFrame =
CFrame.new(humanoidRootPart.Position+OFFSET) * CFrame.new(0, bobOffsetY, 0) *
CFrame.Angles(0, cameraAngle.X, 0) *
CFrame.Angles(cameraAngle.Y, 0, 0) *
CFrame.new(bobOffsetX, 0, 0) * (Rot * Tilt)
end
RunService.RenderStepped:Connect(renderStepped)
OFFSET = InitOffsetAttachment(character)
and heres my prototype ik its very ugly
local runS = game:GetService("RunService")
local Cam = workspace.CurrentCamera
local LocalPlayer = game:GetService("Players").LocalPlayer.Character:WaitForChild("Head"):WaitForChild("FaceFrontAttachment")
local Frame = game:GetService("Players").LocalPlayer.PlayerGui.ScreenGui.Frame
local function SetupAttachment(Char)
local A = Instance.new("Attachment")
A.Parent = Char:WaitForChild("HumanoidRootPart")
A.WorldPosition = Char:WaitForChild("Head").Position + Char:WaitForChild("Head").CFrame.LookVector
return A
end
local Attachment = SetupAttachment(game:GetService("Players").LocalPlayer.Character)
runS.Stepped:Connect(function()
Frame.Position = UDim2.fromOffset(Cam:WorldToViewportPoint(Attachment.WorldPosition).X,Cam:WorldToViewportPoint(Attachment.WorldPosition).Y)
end)

2 comments
Why remake the code when you can just mess around with the variables to find the perfect solution?
it has quite the problems since its in world position and it does not move with the camera although i have already found another solution