Animation delays and makes my system look buggy

Hello creators!
I’m working on a weapon engine for my game, and something that i came across now and in my previous weapon engine is this weird animation delay. All the weapon animations are loaded in onto the character when the character spawns.

Here is my code that I use for the animation.

local Animations = {}
-- // Services
local tweenService = game:GetService("TweenService")

-- // Identifiers
local animationsFolder = game.ReplicatedStorage.WeaponEngine.Animations

-- // Values
local __loadedAnimations = {}

-- // Code
function Animations.findLoadedAnim(AnimName : string, plr : Player)
	local answer = nil
	
	for i,v : AnimationTrack in pairs(__loadedAnimations[plr.Name]) do
		if v.Name == AnimName then
			answer = v
		end
	end
	
	return answer
end

function Animations.loadAllAnimations(plr : Player)
	repeat task.wait() until plr.Character ~= nil
	local Animator : Animator = plr.Character:WaitForChild("Humanoid"):WaitForChild("Animator")
	
	local loadedAnimsForCharacter = {}
	
	for i,v in pairs(animationsFolder:GetDescendants()) do
		if v:IsA("Animation") then
			local LoadedAnim = Animator:LoadAnimation(v)
			table.insert(loadedAnimsForCharacter,LoadedAnim)
		end
	end
	
	if table.find(__loadedAnimations, plr.Name) then
		table.remove(__loadedAnimations,table.find(__loadedAnimations, plr.Name))
	end
	
	__loadedAnimations[plr.Name] = loadedAnimsForCharacter
end

function Animations.playIdleAnim(tool : Tool, plr : Player)
	local SettingsModule = require(tool.Client.Settings)

	if SettingsModule.BaseSettings.__weaponType == "Pistol" then
		local foundIdleAnim = Animations.findLoadedAnim("IdleAnim_Pistol",plr)

		if foundIdleAnim then
			foundIdleAnim:Play()
		end

	elseif SettingsModule.BaseSettings.__weaponType == "Automatic" then
		local foundIdleAnim = Animations.findLoadedAnim("IdleAnim",plr)

		if foundIdleAnim then
			foundIdleAnim:Play()
		end

	elseif SettingsModule.BaseSettings.__weaponType == "Shotgun" then
		local foundIdleAnim = Animations.findLoadedAnim("IdleAnim_Shotgun",plr)

		if foundIdleAnim then
			foundIdleAnim:Play()
		end

	elseif SettingsModule.BaseSettings.__weaponType == "Sniper" then
		local foundIdleAnim = findLoadedAnim("IdleAnim_Sniper",plr)

		if foundIdleAnim then
			foundIdleAnim:Play()
		end
	end
end

function Animations.playEquippAnim(tool : Tool, plr : Player)
	local SettingsModule = require(tool.Client.Settings)
	
	local function boltAnim()
		local animationID = SettingsModule.AnimationSetting.__boltAnimation
		local animationController : AnimationController = tool:FindFirstChild("AnimationController") or Instance.new("AnimationController",tool)
		
		local boltAnimation = Instance.new("Animation")
		boltAnimation.AnimationId = animationID
		boltAnimation.Name = "boltAnimation_"..tool.Name

		local loadedBoltAnim = animationController:LoadAnimation(boltAnimation)
		loadedBoltAnim:Play()
		tool.Bolt.SlidePull:Play()
		
		task.delay(loadedBoltAnim.Length,function()
			loadedBoltAnim = nil
			tool.Bolt.SlideRelease:Play()
		end)
	end

	if SettingsModule.BaseSettings.__weaponType == "Pistol" then
		local foundEquippAnim = Animations.findLoadedAnim("EquipAnim_Pistol",plr)

		if foundEquippAnim then
			tool:SetAttribute("CanFire",false)
			foundEquippAnim:Play()
			task.wait(0.17)
			boltAnim()
			repeat task.wait() until foundEquippAnim.IsPlaying == false
			if not plr.Character:FindFirstChild(tool.Name) then return end
			Animations.playIdleAnim(tool,plr)
			tool:SetAttribute("CanFire",true)
		end

	elseif SettingsModule.BaseSettings.__weaponType == "Automatic" then
		local foundEquippAnim = Animations.findLoadedAnim("IdleAnim",plr)

		if foundEquippAnim then
			foundEquippAnim:Play()
			task.wait(0.17)
			boltAnim()
			repeat task.wait() until foundEquippAnim.IsPlaying == false
			if not plr.Character:FindFirstChild(tool.Name) then return end
			Animations.playIdleAnim(tool,plr)
		end

	elseif SettingsModule.BaseSettings.__weaponType == "Shotgun" then
		local foundEquippAnim = Animations.findLoadedAnim("EquipAnim_Shotgun",plr)
		
		if foundEquippAnim then
			foundEquippAnim:Play()
			task.wait(0.17)
			boltAnim()
			repeat task.wait() until foundEquippAnim.IsPlaying == false
			if not plr.Character:FindFirstChild(tool.Name) then return end
			Animations.playIdleAnim(tool,plr)
		end

	elseif SettingsModule.BaseSettings.__weaponType == "Sniper" then
		local foundEquippAnim = Animations.findLoadedAnim("EquipAnim_Sniper",plr)

		if foundEquippAnim then
			foundEquippAnim:Play()
			task.wait(0.17)
			boltAnim()
			repeat task.wait() until foundEquippAnim.IsPlaying == false
			if not plr.Character:FindFirstChild(tool.Name) then return end
			Animations.playIdleAnim(tool,plr)
		end
	end
end

function Animations.stopIdleAnim(tool : Tool, plr : Player)
	local SettingsModule = require(tool.Client.Settings)

	if SettingsModule.BaseSettings.__weaponType == "Pistol" then
		local foundIdleAnim = Animations.findLoadedAnim("IdleAnim_Pistol",plr)

		if foundIdleAnim then
			foundIdleAnim:Stop()
		end

	elseif SettingsModule.BaseSettings.__weaponType == "Automatic" then
		local foundIdleAnim = Animations.findLoadedAnim("IdleAnim",plr)

		if foundIdleAnim then
			foundIdleAnim:Stop()
		end

	elseif SettingsModule.BaseSettings.__weaponType == "Shotgun" then
		local foundIdleAnim = Animations.findLoadedAnim("IdleAnim_Shotgun",plr)

		if foundIdleAnim then
			foundIdleAnim:Stop()
		end

	elseif SettingsModule.BaseSettings.__weaponType == "Sniper" then
		local foundIdleAnim = Animations.findLoadedAnim("IdleAnim_Sniper",plr)

		if foundIdleAnim then
			foundIdleAnim:Stop()
		end
	end
end

function Animations.playAimingAnim(tool : Tool, plr : Player)
	local SettingsModule = require(tool.Client.Settings)

	if SettingsModule.BaseSettings.__weaponType == "Pistol" then
		local foundIdleAnim = Animations.findLoadedAnim("AimingAnim_Pistol",plr)

		if foundIdleAnim then
			foundIdleAnim.Looped = true
			foundIdleAnim:Play()
		end

	elseif SettingsModule.BaseSettings.__weaponType == "Automatic" then
		local foundIdleAnim = Animations.findLoadedAnim("AimingAnim_AutoMatics",plr)

		if foundIdleAnim then
			foundIdleAnim.Looped = true
			foundIdleAnim:Play()
		end

	elseif SettingsModule.BaseSettings.__weaponType == "Shotgun" then
		local foundIdleAnim = Animations.findLoadedAnim("AimingAnim_Shotgun",plr)

		if foundIdleAnim then
			foundIdleAnim.Looped = true
			foundIdleAnim:Play()
		end

	elseif SettingsModule.BaseSettings.__weaponType == "Sniper" then
		local foundIdleAnim = findLoadedAnim("AimingAnim_Sniper",plr)

		if foundIdleAnim then
			foundIdleAnim.Looped = true
			foundIdleAnim:Play()
		end
	end
end

function Animations.stopAimingAnim(tool : Tool, plr : Player)
	local SettingsModule = require(tool.Client.Settings)

	if SettingsModule.BaseSettings.__weaponType == "Pistol" then
		local foundIdleAnim = Animations.findLoadedAnim("AimingAnim_Pistol",plr)

		if foundIdleAnim then
			foundIdleAnim:Stop()
		end

	elseif SettingsModule.BaseSettings.__weaponType == "Automatic" then
		local foundIdleAnim = Animations.findLoadedAnim("AimingAnim_AutoMatics",plr)

		if foundIdleAnim then
			foundIdleAnim:Stop()
		end

	elseif SettingsModule.BaseSettings.__weaponType == "Shotgun" then
		local foundIdleAnim = Animations.findLoadedAnim("AimingAnim_Shotgun",plr)

		if foundIdleAnim then
			foundIdleAnim:Stop()
		end

	elseif SettingsModule.BaseSettings.__weaponType == "Sniper" then
		local foundIdleAnim = Animations.findLoadedAnim("AimingAnim_Sniper",plr)

		if foundIdleAnim then
			foundIdleAnim:Stop()
		end
	end
end

function Animations.playNonAutomaticShootAnim(tool : Tool, plr : Player)
	local SettingsModule = require(tool.Client.Settings)
	
	local function eachAnimation(playingAnim : AnimationTrack)
		Animations.stopIdleAnim(tool,plr)
		Animations.stopAimingAnim(tool,plr)
		
		task.delay(playingAnim.Length,function()
			Animations.playAimingAnim(tool,plr)
			task.wait(2)
			Animations.stopAimingAnim(tool,plr)
			if tool.Parent == plr.Character then
				Animations.playIdleAnim(tool,plr)
			end
		end)
	end

	if SettingsModule.BaseSettings.__weaponType == "Pistol" then
		local foundIdleAnim = Animations.findLoadedAnim("ShootAnim_Pistol",plr)

		if foundIdleAnim then
			eachAnimation(foundIdleAnim)
			foundIdleAnim:Play()
		end

	elseif SettingsModule.BaseSettings.__weaponType == "Automatic" then
		local foundIdleAnim = Animations.findLoadedAnim("ShootAnim_AutoMatics",plr)

		if foundIdleAnim then
			eachAnimation(foundIdleAnim)
			foundIdleAnim:Play()
		end

	elseif SettingsModule.BaseSettings.__weaponType == "Shotgun" then
		local foundIdleAnim = Animations.findLoadedAnim("ShootAnim_Shotgun",plr)

		if foundIdleAnim then
			eachAnimation(foundIdleAnim)
			foundIdleAnim:Play()
		end

	elseif SettingsModule.BaseSettings.__weaponType == "Sniper" then
		local foundIdleAnim = Animations.findLoadedAnim("ShootAnim_Sniper",plr)

		if foundIdleAnim then
			eachAnimation(foundIdleAnim)
			foundIdleAnim:Play()
		end
	end
end

function Animations.StopAllAnims(tool : Tool, plr : Player)
	for i,v : AnimationTrack in pairs(__loadedAnimations[plr.Name]) do
		v:Stop()
	end
end

return Animations

Please ignore that is says “foundIdleAnim” on every animation, messed up the organization of that area.

Here is a video demonstration the problem:


You can see this delay happen clearly when I shoot the weapon for the first time. The hand that does not hold the tool goes back down to the torso, and then it goes to play the animation

This delay makes the weapon look buggy. As it happened to me before, I though that loading the animations onto the character when it spawns would fix this.

Thank you for your help and attention!

1 Like

You have to preload these animations, you can do the following:

local ContentProvider = game:GetService("ContentProvider")
local animation1 = Instance.new("Animation")
animation1.AnimationId = id
animation1.Name = "anim1"
-- other animations
local preloadAnimations = {animation1, animation2} 
ContentProvider:PreloadAsync(preloadAnimations)
2 Likes

Should I preload before I do :LoadAnimation() ?
Thanks.

No I don’t think it matters, I did it after and it worked fine for me

Alright, let me try it out and if it works I’ll mark you as the answer.
Thank you! I hope this will work. :slight_smile:

Oops never mind, I did it before LoadAnimation. But try both as it might not matter after all.

Should I do it every time the character respawns or just once?

Preloading once should be enough

Should this be on the client or server?

content preloading can only be done in local scripts (the client)

Yeah, I am a dummy lol. That makes sense.

Nah its all good. For organization sake, create a local script in replicated first named “Preloader” (it can be anything you’d like lol)

I got my engine organized with module scripts. But thank you for the tip, maybe someone will need it in the future.

This worked! Thank you for the solution!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.