My Animation function sometimes doesn't play animations?

  1. What do you want to achieve?
    I’ve coded my own function for playing animations, it runs on the client of course just so it could possibly be more optimised and more.

  2. What is the issue?
    Sometimes when playing in game the animations refuse to load or play after a long delay. Or play when it attempts to play another animation for someone else. For example, if I use an attack. It won’t show until someone else does said attack..

  3. What solutions have you tried so far?
    I’ve tried to rename the animations, use task.spawn to try and get it to run better? I’ve generally had mixed thoughts with how to go about with this.

Here’s my code:

function PlayAnimation(InfoTable)
	task.spawn(function()
		local Model = InfoTable.Model
		local AnimObj = InfoTable.AnimObj
		local ForceOverwrite = InfoTable.ForceOverwrite
		local Priority = InfoTable.Priority
		local StayOnLastFrame = InfoTable.StayOnLastFrame
		local Reversed = InfoTable.Reversed
		local OnEnd = InfoTable.OnEnd
		local StopAnim = InfoTable.StopAnim

		if (Model and AnimObj) then
			if Model:FindFirstChild("Humanoid") then
				local Humanoid = Model:FindFirstChild("Humanoid")
				local Animator = Humanoid:WaitForChild("Animator")

				if AnimObj:IsA("Folder") then
					local AllAnimations = AnimObj:GetChildren()
					local RandomAnimation = AllAnimations[math.random(1, #AllAnimations)]

					if RandomAnimation.Name == PreviousAnimationName then
						repeat task.wait()
							RandomAnimation = AllAnimations[math.random(1, #AllAnimations)]
						until RandomAnimation.Name ~= PreviousAnimationName

						AnimObj = RandomAnimation
					else
						AnimObj = RandomAnimation
					end
				end

				local AnimTracks = Animator:GetPlayingAnimationTracks()
				PreviousAnimationName = AnimObj.Name

				if ForceOverwrite and ForceOverwrite == true then StopAllAnims(Humanoid) end

				if Humanoid and Humanoid.Health > 0 then
					if StopAnim then FuncAssistor.StopAnimation(Model, StopAnim) return end

					local Track = RetrieveAnimation(Animator, AnimObj)
					if Priority and Enum.AnimationPriority[Priority] then Track.Priority = Enum.AnimationPriority[Priority] end

					for _, MiscInfo in pairs(AnimObj:GetChildren()) do
						task.spawn(function()
							if MiscInfo:IsA("Sound") then
								if MiscInfo:FindFirstChild("Delay") then
									task.wait(MiscInfo:FindFirstChild("Delay").Value)
									RemoteEvents.PlaySound:FireServer(MiscInfo, Model.PrimaryPart)
								end
							end
						end)
					end

					local DefaultSpeed = Model:GetAttribute("TimeScale")

					Track:Play()
					if AnimObj:GetAttribute("Speed") then DefaultSpeed += AnimObj:GetAttribute("Speed") end
					Track:AdjustSpeed(DefaultSpeed)

					if Reversed then Track:AdjustSpeed(-1) end

					task.spawn(function()
						if OnEnd then
							task.wait(Track.Length)

							local InfoTable = {}

							if Model then InfoTable.Model = Model end
							if AnimObj then InfoTable.AnimObj = OnEnd end
							if ForceOverwrite then InfoTable.ForceOverwrite = ForceOverwrite end
							if Priority then InfoTable.Priority = Priority end
							if StayOnLastFrame then InfoTable.StayOnLastFrame = StayOnLastFrame end
							if Reversed then InfoTable.Reversed = Reversed end

							RemoteEvents.PlayAnimation:FireServer(InfoTable)
						end
					end)

					if StayOnLastFrame then
						if CurrentTrackConn then CurrentTrackConn:Disconnect() StopAllAnims(Humanoid) end

						CurrentTrackConn = Track.Stopped:Connect(function()
							Track:Play(0, 1, 0)
							Track.TimePosition = Track.Length - .00001
						end)
					else
						Track.Stopped:Connect(function()
							FuncAssistor.StopAnimation(Model, AnimObj.Name)
						end)
					end
				end
			end
		end
	end)
end
1 Like

I’m assuming PreviousAnimationName is previously defined as a global function.

Can you send the RetrieveAnimation function?

Sure!

Here it is:

local function RetrieveAnimation(Animator:Animator, AnimObject)
	LoadedAnims[Animator] = LoadedAnims[Animator] or {}
	
	if LoadedAnims[Animator][AnimObject] then return LoadedAnims[Animator][AnimObject] end
	
	LoadedAnims[Animator][AnimObject] = Animator:LoadAnimation(AnimObject)
	return LoadedAnims[Animator][AnimObject]
end

A problem I also found out was that there seemed to be some sort of queue system??? I’m not sure but if I use a move and the ability doesn’t load.. It plays it on the next animation.