Smoothly switching between 2 CFrames

I have a viewmodel script, it checks for when the player is moving and if they are, it gives it a sway animation using math.sin.

My problem is, whenever it switches back, it snaps, how could i get it to smoothly switch back to a non swaying position?

local RunService = game:GetService("RunService")

local Tool = script.Parent.Parent

local Camera = game.Workspace.CurrentCamera

local Character = game.Players.LocalPlayer.Character or game.Players.LocalPlayer.CharacterAdded:Wait()
local Humanoid = Character:WaitForChild("Humanoid")
local HumRoot = Character:WaitForChild("HumanoidRootPart")
local Animator = Humanoid:WaitForChild("Animator")


for i, part in pairs(Tool.Shotgun:GetDescendants()) do
	if part:IsA("BasePart") then
		part.LocalTransparencyModifier = 1
	end
end

local function ToolEquipped()

	local V_Viewmodel = game.ReplicatedStorage.Viewmodels.ViewmodelShotgun1:Clone()

	V_Viewmodel.Parent = game.Workspace

	local V_Humanoid = V_Viewmodel:WaitForChild("Humanoid")
	local V_Animator = V_Humanoid:WaitForChild("Animator")


	local ShotgunHoldTrack = V_Animator:LoadAnimation(script.ShotgunHold)
	ShotgunHoldTrack:Play()

	local t = 0

	local SetViewPosition = RunService.RenderStepped:Connect(function (dt)


		if HumRoot.AssemblyLinearVelocity.Magnitude < 1 then
			t=0
			V_Viewmodel:PivotTo(Camera.CFrame * CFrame.new(0,-4.5, 0.55))
		else
			t += dt
			local GunShake = math.sin(t * 5) * 0.1
			print(GunShake)
			V_Viewmodel:PivotTo(Camera.CFrame * CFrame.new(0 + GunShake,-4.5 + GunShake, 0.55))
			
		end

	end)


	Tool.Unequipped:Connect(function ()
		SetViewPosition:Disconnect()
		V_Viewmodel:Destroy()
	end)

end


Tool.Equipped:Connect(ToolEquipped)
1 Like

You can lerp it back to the original position, if the player isn’t moving.

Or add a math.pi inside the sine wave, but im not sure this will work.

2 Likes

Sorry I redid, the script, here is the vital part I want fixed

	local SetViewPosition = RunService.RenderStepped:Connect(function (dt)

		local DefaultGunShake = math.sin(tick() * 2) * 0.05

		if HumRoot.AssemblyLinearVelocity.Magnitude < 1 then
			t=0
			V_Viewmodel:PivotTo(Camera.CFrame * CFrame.new(0 + DefaultGunShake,-4.5 + DefaultGunShake, 0.55))
		else
			t += dt
			local GunShake = math.sin(t * 5) * 0.1
			V_Viewmodel:PivotTo(Camera.CFrame * CFrame.new(0 + GunShake,-4.5 + GunShake, 0.55))
			
		end

	end)
currentCFrame:Lerp(newCFrame, alpha)

returns a new cframe that is in between the current cframe and the new cframe
how close this cframe is to the new cframe is represented by alpha ( number between 0 and 1 representing 0% and 100%)

if you do one lerp per renderstepped loop then it creates a smooth movement
if you want to adjust the speed then you change alpha

1 Like

sorry to ask but could you help me out with that? i dont use lerp very often

local alpha = 0.5 -- adjust to whatever looks best

--in this part,
local currentCFrame = V_Viewmodel:GetPivot()
local targetCframe = camera.CFrame * CFrame.new(0 + DefaultGunShake,-4.5 + DefaultGunShake, 0.55)

--so the new cframe is
local newCFrame = currentCFrame:Lerp(targetCFrame, alpha)

--then move to the new cframe
V_Viewmodel:PivotTo(newCFrame)
1 Like
	local SetViewPosition = RunService.RenderStepped:Connect(function (dt)

		local CurrentCFrame = V_Viewmodel:GetPivot()

		if HumRoot.AssemblyLinearVelocity.Magnitude < 1 then
			
			t=0
			local DefaultGunShake = math.sin(tick() * 2) * 0.05
			
			local TargetCFrame = Camera.CFrame * CFrame.new(0 + DefaultGunShake,-4.5 + DefaultGunShake, 0.55)
			local NewCFrame = CurrentCFrame:Lerp(TargetCFrame, 0.9)
			V_Viewmodel:PivotTo(NewCFrame)
			
		else
			t += dt
			local GunShake = math.sin(t * 5) * 0.1
			V_Viewmodel:PivotTo(Camera.CFrame * CFrame.new(0 + GunShake,-4.5 + GunShake, 0.55))

		end

	end)

the problem with this is it starts off alright but when not moving it just keeps going further and further off the screen.

Because the lerp makes it drop, and then it sets the currentCFrame as that, and it keeps sinking further and further til’ it clips through the floor.