Help with viewmodel bobbing!

I am creating a better fps system and I need to know how i could smoothly transition between walking and now walking with this module I created.

local module = {}

local swayOffset = CFrame.new()
ccp = game.Workspace.CurrentCamera.CFrame

local TweenService = game:GetService("TweenService")
local TweenTime = 0.3 -- Amount of time for transmission
local startTime = 0
local Intensity = 0.6
local lastState = 0
local t = tick()

function module.renderloop(vm, mult, plr) --bind this camera render loop
	vm.PrimaryPart.CFrame = game.Workspace.CurrentCamera.CFrame * CFrame.new(0,0,0)
	if plr.Character.Humanoid.MoveDirection.Magnitude > 0 then
		local t = tick()
		if lastState == 0 then
			lastState = 1
			startTime = t
		end

		local xRotation = math.cos(t * 7) * 5
		local yRotation = math.abs(math.sin(t * 7)) * 5

		local alpha = (TweenService:GetValue(math.min((t - startTime) / TweenTime, 1), Enum.EasingStyle.Cubic, Enum.EasingDirection.Out))

		-- Create rotation CFrame for X, Y, and Z axes
		local xRotationCFrame = CFrame.Angles(0, math.rad(xRotation * alpha * Intensity), 0)
		local yRotationCFrame = CFrame.Angles(math.rad(yRotation * alpha * Intensity), 0, 0)
		local zRotationCFrame = CFrame.Angles(0, 0, math.rad(0))  -- You can add Z-axis rotation here if needed

		-- Combine the rotations
		local rotationCFrame = xRotationCFrame * yRotationCFrame * zRotationCFrame

		-- Apply the rotation to the character
		vm.PrimaryPart.CFrame = game.Workspace.CurrentCamera.CFrame * rotationCFrame
	end
	local rotation = workspace.CurrentCamera.CFrame:toObjectSpace(ccp) --get cframe delta.
	local x,y,z = rotation:ToOrientation() --I'm sure there are better ways to get rotation but this will work for now.
	swayOffset = swayOffset:Lerp(CFrame.Angles(math.sin(x)*mult,math.sin(y)*mult,0), 0.1) --calculate the sway using SIN
	vm.Handle.CFrame = vm.Handle.CFrame * swayOffset --apply the sway
	ccp = game.Workspace.CurrentCamera.CFrame
end

return module

every time I stop moving it snaps into the main position, how would I make it smoothly transition.

I’ve made a few adjustments to your code which might help with your request.
I’m not able to test it as of right now but hopefully the code works or can be used for knowledge/ideas.

Let me know if the code doesn’t work or if there are any other questions. :+1:

local module = {}

local swayOffset = CFrame.new()
local ccp = game.Workspace.CurrentCamera.CFrame

local TweenService = game:GetService("TweenService")
local TweenTime = 0.3 -- Amount of time for transition
local Intensity = 0.6
local isWalking = false
local lastState = false
local t = tick()

function module.renderloop(vm, mult, plr)
    vm.PrimaryPart.CFrame = game.Workspace.CurrentCamera.CFrame * CFrame.new(0,0,0)

    local walking = plr.Character.Humanoid.MoveDirection.Magnitude > 0
    if walking ~= isWalking then
        local t = tick()
        if lastState == false then
            lastState = true
            local startTime = t
            local startOffset = swayOffset
            local endOffset = CFrame.new()
            
            local tweenInfo = TweenInfo.new(TweenTime, Enum.EasingStyle.Cubic, Enum.EasingDirection.Out)
            local tween = TweenService:Create(
                swayOffset,
                tweenInfo,
                {Value = endOffset}
            )
            
            tween:Play()
            tween.Completed:Wait()
            
            swayOffset = endOffset
        end
    end

    if walking then
        local xRotation = math.cos(t * 7) * 5
        local yRotation = math.abs(math.sin(t * 7)) * 5

        local alpha = (TweenService:GetValue(math.min((t - startTime) / TweenTime, 1), Enum.EasingStyle.Cubic, Enum.EasingDirection.Out))

        local xRotationCFrame = CFrame.Angles(0, math.rad(xRotation * alpha * Intensity), 0)
        local yRotationCFrame = CFrame.Angles(math.rad(yRotation * alpha * Intensity), 0, 0)
        local zRotationCFrame = CFrame.Angles(0, 0, math.rad(0))

        local rotationCFrame = xRotationCFrame * yRotationCFrame * zRotationCFrame

        vm.PrimaryPart.CFrame = game.Workspace.CurrentCamera.CFrame * rotationCFrame
    end

    local rotation = workspace.CurrentCamera.CFrame:toObjectSpace(ccp)
    local x,y,z = rotation:ToOrientation()
    swayOffset = swayOffset:Lerp(CFrame.Angles(math.sin(x)*mult,math.sin(y)*mult,0), 0.1)
    vm.Handle.CFrame = vm.Handle.CFrame * swayOffset
    ccp = game.Workspace.CurrentCamera.CFrame

    isWalking = walking
end

return module

1 Like