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.