Module doesn't work

Hi, I have made this AnimationModule which handles animations easily, rather than me callling an animation on each client script, but it doesn’t seem to work.

Module Script:

local Animations = {}

local Services = {
	RunService = game:GetService("RunService")
}

local CurrentAnimation 
local Heartbeat = Services.RunService.Heartbeat

function Animations:Play(Player, Animation, Duration)
	local Character = Player.Character or Player.CharacterAdded:Wait()
	local Humanoid = Character:WaitForChild("Humanoid")
	
	local Animator = Humanoid:WaitForChild("Animator")
	local Animation = Animator:LoadAnimation(Animation)
	
	if Duration ~= nil and CurrentAnimation == nil then
		Animation:Play(Duration)
		CurrentAnimation = Animation
	elseif Duration == nil and CurrentAnimation == nil then
		Animation:Play()
		CurrentAnimation = Animation
	elseif Duration ~= nil and CurrentAnimation then
		repeat Heartbeat:Wait() until CurrentAnimation == nil
		Animation:Play(Duration)
		CurrentAnimation = Animation
	elseif Duration == nil and CurrentAnimation then
		repeat Heartbeat:Wait() until CurrentAnimation == nil
		Animation:Play()
		CurrentAnimation = Animation
	end
end

function Animations:Stop(Player, Animation, Duration)
	if Duration ~= nil and CurrentAnimation ~= nil then
		CurrentAnimation:Stop(Duration)
		CurrentAnimation = nil
	elseif Duration == nil and CurrentAnimation ~= nil then
		CurrentAnimation:Stop()
		CurrentAnimation = nil
	end
end

return Animations
if Back then -- by the way this is just the animation variable.
AnimationModule:Play(plr, Back, 0.5)
end

Any help would be appreciated, thanks.

3 Likes

are you ok? i will use a dot then…

Still doesn’t work [char limit]

I see something, i have two of the exact same variables, I will change them and see what happens.

I’m confused to why you need all these waits? This script seems extremely inefficient… But maybe I just don’t know enough about what you’re trying to do

1 Like

self access > constructor format

there may be a better way of doing this, but i dont want two animations to be playing at once, so i have all the waits until the current animation is nothing then i play the animation i want

If you’re going to manually set the speed, make sure to do 1/Duration to ensure it gets applied correctly.

I recommend using a dynamic approach when it comes to looking for the player character + humanoid instead of using waits.

Don’t use a single variable for an animation when there’s a possibility for multiple animations to be played, it’s not good practice in the long run.

Use BindableEvents instead of loop checking with Heartbeat:Wait(), make it a lot more efficient.

2 Likes

Why not loop through all running animations and stop them before playing the new animation?

1 Like

Not sure if this helps but I wrote this script that Loads, Plays and Stops animations. Feel free to edit it to work in a module. It has a cache system so that animations don’t need to be loaded more than once:

local Cache = {}

function GetAnimator(Player)
	local Character = Player.Character
	if not Character then
		return
	end
	local Humanoid = Character:FindFirstChild("Humanoid");
	if not Humanoid then
		return
	end
	local Animator = Humanoid:FindFirstChild("Animator");
	return Animator
end

function LoadAnimation(Player,Animation)
	Cache[Player] = Cache[Player] or {}
	local Anim = Cache[Player][Animation];
	if not Anim then
		local Animator = GetAnimator(Player);
		if not Animator then
			return
		end
		Anim = Animator:LoadAnimation(Animation);
		Cache[Player][Animation] = Anim;
	end
	return Anim
end

function StopAnimations(Player)
	if not Cache[Player] then
		return
	end
	for _,Anim in pairs(Cache[Player]) do
		Anim:Stop()
	end
end

function PlayAnimation(Player,Animation)
	local Anim = LoadAnimation(Player,Animation);
	if not Anim then
		return warn("Error retrieving/loading Animation")
	end
	StopAnimations(Player);
	Anim:Play();
end
2 Likes

Nice, thank you! Is there any modifications I need to make if I wanted to load in two animations at once?

You can just call the LoadAnimation separately from PlayAnimation. If you just want to play an animation that’s already loaded or not loaded the PlayAnimation function will load it before playing.

So if you want to load 2 animations just do:
local Anim1 = LoadAnimation(Player,Animation);
local Anim2 = LoadAnimation(Player,Animation):

Ok, and one more thing, what if i wanted to stop an animation early if a certain condition has been met?

In that case you’d want a separate function for stopping a single animation rather than stopping all of them. You could do this:

function StopAnimation(Player,Animation)
	if not Cache[Player] then
		return
	end
	local Anim = Cache[Player][Animation];
	if not Anim then
		return
	end
	Anim:Stop()
end

Then whenever that certain condition is met just called
StopAnimation(Player,Animation);

Thanks, I have added this, but when I play an animation, stop an animation then play the same animation again then try to stop it, it does not stop

It only happens in this section of code, every other code it stops when a certain condition is met:

UserInputService.InputBegan:Connect(function(Input , GPE)
    if Input.KeyCode ~= Enum.KeyCode[Keybind] then return end
    if GPE then return end
	Animations:PlayAnimation(Player, Animation)
end)

UserInputService.InputEnded:Connect(function(Input , GPE)
 if Input.KeyCode ~= Enum.KeyCode[Keybind] then return end
Animations:StopAnimation(Player, Animation)
	
end)
1 Like

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