Viewmodel acting wierd sometimes

Hello. So I made a viewmodel for a FPS game that I’m working on, and I’m working on the animation part of it and for some reason if I aim and shoot real fast then I stop aiming and shoot normally, the viewmodel shakes when the animation stops playing. Then if I shoot normally again the bug isn’t there anymore.

(I slowed the animation down so you can see the viewmodel shake)

Notice how right after I stop aiming, then I shoot again the viewmodel shakes then if I keep shooting the viewmodel doesn’t shake.

Here is the code:

local viewModel = game:GetService("ReplicatedStorage"):WaitForChild("ViewModel"):Clone()
local UIS = game:GetService("UserInputService")
local character = script.Parent
local humanoid = character:WaitForChild("Humanoid")
local spring = require(game:GetService("ReplicatedStorage"):WaitForChild("Spring"))
local mySpring = spring.create()
local movementSpring = spring.create()
local viewBobbAddition = 2
local viewBobbSpeed = 2
local viewBobbModifier = .1
local viewBobbModifierOffset = 2.5
local amp = 10
local jump = false
local cameraChanged = game:GetService("ReplicatedStorage"):WaitForChild("ChangedCameraMode")
local connection = nil
local state = "Walk"
local animations = {}
local mouse = false
local conf = require(viewModel:WaitForChild("Gun").SettingsReturn)()
local canShoot = true
viewModel.Parent = workspace.CurrentCamera
-- Load the Animations So they are ready to play right off the bat.
local animationInstance = viewModel:WaitForChild("Run")
animation1 = viewModel:WaitForChild("Humanoid"):WaitForChild("Animator"):LoadAnimation(animationInstance)
local animationInstance = viewModel:WaitForChild("Hold")
animation2 = viewModel:WaitForChild("Humanoid"):WaitForChild("Animator"):LoadAnimation(animationInstance)
local animationInstance = viewModel:WaitForChild("Aim")
animation3 = viewModel:WaitForChild("Humanoid"):WaitForChild("Animator"):LoadAnimation(animationInstance)
local animationInstance = viewModel:WaitForChild("Recoil1")
animation4 = viewModel:WaitForChild("Humanoid"):WaitForChild("Animator"):LoadAnimation(animationInstance)
local animationInstance = viewModel:WaitForChild("Recoil2")
animation5 = viewModel:WaitForChild("Humanoid"):WaitForChild("Animator"):LoadAnimation(animationInstance)

coroutine.wrap(function()
	local animationInstance = viewModel:WaitForChild("Hold")
	local animation = viewModel:WaitForChild("Humanoid"):WaitForChild("Animator"):LoadAnimation(animationInstance)
	animation:Play()
	table.insert(animations, animation)	
end)()

local i = 0
local function getBobbing(addition, speed, modifier)
	return math.sin(i * addition * speed) * modifier
end

local prevUpVel = 0
function connect()
	connection = game:GetService("RunService").RenderStepped:Connect(function(dt)

		i = i + 1 * dt
		viewModel:SetPrimaryPartCFrame(workspace.CurrentCamera.CFrame)
		
		if state == "Run" then
			local SomeCFrame = viewModel.Head.CFrame
			local RX, RY, RZ = SomeCFrame:ToOrientation()
			local RX, _, RZ = character.HumanoidRootPart.CFrame:ToOrientation()
			viewModel:SetPrimaryPartCFrame(CFrame.new(viewModel.Head.CFrame.Position) * CFrame.fromOrientation(RX, RY, RZ))
		end
		local movementSway = Vector3.new(0, 0, 0)
		if script.Parent:FindFirstChild("HumanoidRootPart") then
			if script.Parent:FindFirstChild("HumanoidRootPart").Velocity:Dot(script.Parent:FindFirstChild("HumanoidRootPart").CFrame.LookVector) ~= 0 then
				movementSway = (Vector3.new(getBobbing(5, viewBobbSpeed, viewBobbModifier), getBobbing(10, viewBobbSpeed, viewBobbModifier), getBobbing(10, viewBobbSpeed, viewBobbModifier)) / 25) * 60 * dt * script.Parent:FindFirstChild("HumanoidRootPart").Velocity:Dot(script.Parent:FindFirstChild("HumanoidRootPart").CFrame.LookVector)
			end

			if jump then
				jump = false
				movementSway = Vector3.new(getBobbing(viewBobbAddition, viewBobbSpeed * 2, viewBobbModifier) + viewBobbModifierOffset, getBobbing(viewBobbAddition, viewBobbSpeed * 2, viewBobbModifier) + viewBobbModifierOffset, getBobbing(viewBobbAddition, viewBobbSpeed * 2, viewBobbModifier) + viewBobbModifierOffset)
			end
			prevUpVel = script.Parent:FindFirstChild("HumanoidRootPart").Velocity:Dot(script.Parent:FindFirstChild("HumanoidRootPart").CFrame.UpVector)
		end
		local mouseDelta = game:GetService("UserInputService"):GetMouseDelta()
		mySpring:shove(Vector3.new(-mouseDelta.X / 50, -mouseDelta.Y / 50, 0))
		movementSpring:shove(movementSway)
		local movement = mySpring:update(dt)
		local movement2 = movementSpring:update(dt)
		viewModel:SetPrimaryPartCFrame(viewModel.Head.CFrame:ToWorldSpace(CFrame.Angles(math.rad(movement.Y * amp), math.rad(movement.X * amp), math.rad(movement.Z * amp))))
		viewModel:SetPrimaryPartCFrame(viewModel.Head.CFrame:ToWorldSpace(CFrame.Angles(math.rad(movement2.Y * amp), math.rad(movement2.X * amp), math.rad(movement2.Z * amp))))
	end)
end
connect()

humanoid.StateChanged:Connect(function(_, state)
	if state == Enum.HumanoidStateType.Landed then
		jump = true
	end
end)

humanoid.Died:Connect(function()
	connection:Disconnect()
	viewModel:Destroy()
end)

cameraChanged.Event:Connect(function(mode)
	if mode == "FirstPerson" then
		viewModel.Parent = workspace
		connect()
	else
		viewModel.Parent = game:GetService("ReplicatedStorage")
		connection:Disconnect()
	end
end)

UIS.InputBegan:Connect(function(input, gameProcessed)
	--if not gameProcessed then
	if input.UserInputType == Enum.UserInputType.MouseButton2 then
		mouse = true
		canShoot = false
		local animation = game:GetService("ReplicatedStorage"):WaitForChild("States"):WaitForChild("Aim"):Invoke()
		local FOV = conf.AimFOV
		workspace.CurrentCamera.FieldOfView = FOV
		canShoot = true
	end
	--end
end)

UIS.InputEnded:Connect(function(input, gameProcessed)
	--if not gameProcessed then
	if input.UserInputType == Enum.UserInputType.MouseButton2 then
		
		mouse = false
		canShoot = false
		local animation = game:GetService("ReplicatedStorage"):WaitForChild("States"):WaitForChild("Walk"):Invoke()
		workspace.CurrentCamera.FieldOfView = 70	
		canShoot = true	
	end
	--end
end)

game:GetService("ReplicatedStorage"):WaitForChild("States"):WaitForChild("Shoot1").OnInvoke = function()
	if state ~= "Run" then
		if canShoot then
			local anims = viewModel:WaitForChild("Humanoid"):GetPlayingAnimationTracks()
			for i, v in ipairs(anims) do
				v:Stop()
			end
			print(viewModel:WaitForChild("Humanoid"):GetPlayingAnimationTracks())
			state = "Shoot1"
			animation4:Play()
			return animation4 -- Return the animation so the "GunModule" can wait for it to be done, and then let the player shoot again.
		end
	end
end

game:GetService("ReplicatedStorage"):WaitForChild("States"):WaitForChild("Shoot2").OnInvoke = function()
	if state ~= "Run" then
		if canShoot then
			local anims = viewModel:WaitForChild("Humanoid"):GetPlayingAnimationTracks()
			for i, v in ipairs(anims) do
				v:Stop()
			end
			state = "Shoot2"
			animation5:Play()
			return animation5 -- Return the animation so the "GunModule" can wait for it to be done, and then let the player shoot again.
		end
	end
end

game:GetService("ReplicatedStorage"):WaitForChild("States"):WaitForChild("Aim").OnInvoke = function()
	local anims = viewModel:WaitForChild("Humanoid"):GetPlayingAnimationTracks()
	for i, v in ipairs(anims) do
		v:Stop()
	end
	state = "Aim"
	animation3:Play()
	return animation3
end

game:GetService("ReplicatedStorage"):WaitForChild("States"):WaitForChild("Run").Event:Connect(function()
	local anims = viewModel:WaitForChild("Humanoid"):GetPlayingAnimationTracks()
	for i, v in ipairs(anims) do
		v:Stop()
	end
	state = "Run"
	animation1:Play()
end)

game:GetService("ReplicatedStorage"):WaitForChild("States"):WaitForChild("Walk").OnInvoke = function()
	local anims = viewModel:WaitForChild("Humanoid"):GetPlayingAnimationTracks()
	for i, v in ipairs(anims) do
		v:Stop()
	end
	state = "Walk"
	animation2:Play()	
	return animation2
end

game:GetService("ReplicatedStorage"):WaitForChild("GetState").OnInvoke = function()
	return state
end

coroutine.wrap(function()
	require(viewModel.Gun.GunModule)
end)()

Gun Module code:

local module = {}
local UIS = game:GetService("UserInputService")
local mouse = false
local debounce = false

function module:Fire()
	if not debounce then
		debounce = true
		local lastState = game:GetService("ReplicatedStorage"):WaitForChild("GetState"):Invoke()
		if lastState ~= "Run" then
			if lastState == "Walk" then
				local animation = game:GetService("ReplicatedStorage"):WaitForChild("States"):WaitForChild("Shoot1"):Invoke()
				if animation then animation.Stopped:Wait() else debounce = false return end
				
				game:GetService("ReplicatedStorage"):WaitForChild("GunFire"):FireServer()
				game:GetService("ReplicatedStorage"):WaitForChild("States"):WaitForChild("Walk"):Invoke()
				debounce = false
			elseif lastState == "Aim" then
				local animation = game:GetService("ReplicatedStorage"):WaitForChild("States"):WaitForChild("Shoot2"):Invoke()
				if animation then animation.Stopped:Wait() else debounce = false return end
				
				game:GetService("ReplicatedStorage"):WaitForChild("GunFire"):FireServer()
				game:GetService("ReplicatedStorage"):WaitForChild("States"):WaitForChild("Aim"):Invoke()
				debounce = false
			end
		end
	end
end

UIS.InputBegan:Connect(function(inputObject, gamePorcessed)
	if inputObject.UserInputType == Enum.UserInputType.MouseButton1 then
		mouse = true
		module:Fire()
	end
end)

UIS.InputEnded:Connect(function(inputObject, gamePorcessed)
	if inputObject.UserInputType == Enum.UserInputType.MouseButton1 then
		mouse = false
	end
end)

return module

The gun module basically detects when the player shoots and stuff.

Could someone please help me fix this bug? I’ve been having this for over the past 2 weeks or so, and it’s really starting to annoy me alot.

1 Like