Help with my combo system please

Hi, I’m trying to make a combo system for my sword, but I’m really stuck and the code doesn’t work, could you please help me?

This is the code:

local InCombo = false
local ComboStep = 0 

local avaibleAttackAnimations = {7292031028, 7289385180, 7305181383} 

local animationn = Instance.new("Animation", player.Character) 
animationn.Name = "AttackAnimation" 
animationn.AnimationId = "rbxassetid://"..tostring(7292031028) 

local animation22 = Instance.new("Animation", player.Character) 
animation22.Name = "AttackAnimation" 
animation22.AnimationId = "rbxassetid://"..tostring(7289385180) 

local animation33 = Instance.new("Animation", player.Character) 
animation33.Name = "AttackAnimation" 
animation33.AnimationId = "rbxassetid://"..tostring(7305181383) 

local animation = Character.Humanoid:LoadAnimation(animationn)
local animation2 = Character.Humanoid:LoadAnimation(animation22)
local animation3 = Character.Humanoid:LoadAnimation(animation33)

function combo()
	ComboStep = ComboStep + 1
	script.Attack:FireServer()
	script.Sounds.noToca:Play()
	Trail.Transparency = NumberSequence.new(0.9)
	Humanoid.WalkSpeed = 4
	CanAttack = false
	animation:Play()
	wait(0.5)
	if equipped == true then idle:Play() end -- check bool
	CanAttack = true

end


function combo2()
	ComboStep = ComboStep + 1
	script.Attack:FireServer()
	script.Sounds.noToca:Play()
	Trail.Transparency = NumberSequence.new(0.9)
	Humanoid.WalkSpeed = 4
	CanAttack = false
	animation2:Play()
	wait(0.5)
	if equipped == true then idle:Play() end -- check bool
	CanAttack = true

end


function combo3()
	ComboStep = ComboStep + 1
	script.Attack:FireServer()
	script.Sounds.noToca:Play()
	Trail.Transparency = NumberSequence.new(0.9)
	Humanoid.WalkSpeed = 4
	CanAttack = false
	animation3:Play()
	wait(0.5)
	if equipped == true then idle:Play() end -- check bool
	CanAttack = true
	Humanoid.WalkSpeed = 16
	ComboStep = 0
	InCombo = false
end

script.Parent.Activated :Connect(function()
	if CanAttack == true and player.Character.CanDamage.Value == true and Character.IsBlocking.Value == 0 then

		if InCombo then
			if ComboStep == 1 then
				print(1)
				delay(0.5,combo)
				
			end
			
			if ComboStep == 2 then
				print(2)
				delay(0.5 ,combo2)
			end
			
			if ComboStep == 3 then
				print(3)
				delay(0.5,combo3)
			end
		else -- start combo
			ComboStep = 1
			InCombo = true
			script.Attack:FireServer()
			script.Sounds.noToca:Play()
			Trail.Transparency = NumberSequence.new(0.9)
			Humanoid.WalkSpeed = 4
			CanAttack = false
			wait(0.5)
			Trail.Transparency = NumberSequence.new(1)
			wait(0.5)
			if equipped == true then idle:Play() end -- check bool
			CanAttack = true
			Humanoid.WalkSpeed = 16
		end

	end
	
end)

I really need help please, I have never created a combo system

You haven’t mentioned what went wrong and it’s difficult to find out what went wrong as we don’t have access to the variables in the function (invoke server remote events, animations), hence people won’t help and respond to the post.

I’m assuming it doesn’t work because the if statement criteria, if it fails there is nothing to let you know what went wrong.

Like the CanAttack variable, I have never seen it defined anywhere in the script so it’s probably nil, hence this if statement will fail and the script will never run at all.

Consequently, I recommend using a table to better organize it like so (sample code don’t copy and paste), organizing your animations in an array, and cycle from 1-4. Additionally you can store your combo function in a table as well:

this is the code with the variables, now I will organize the animations

local CanAttack = true

local player = game:GetService("Players").LocalPlayer
repeat wait() until player and player:HasAppearanceLoaded()
local Character = player.Character
local Humanoid = Character:WaitForChild("Humanoid")


local idle = Character:WaitForChild("Humanoid").Animator:LoadAnimation(script.Animaciones.Idle)



local run = Character:WaitForChild("Humanoid").Animator:LoadAnimation(script.Animaciones.Run)
local sacar = Character:WaitForChild("Humanoid").Animator:LoadAnimation(script.Animaciones.Sacar)
local poner = Character:WaitForChild("Humanoid").Animator:LoadAnimation(script.Animaciones.Poner)
local Trail = script.Parent.Katana1.Trail

local equipped = false -- bool

script.Parent.Equipped:Connect(function()
	script.Parent.Equipado.Value = true
	Trail.Transparency = NumberSequence.new(0.9)
	Humanoid.WalkSpeed = 4
	sacar:Play()
	script.Sounds.Sacar:Play()
	wait(1)
	idle:Play(); equipped = true
	Humanoid.WalkSpeed = 16
	Trail.Transparency = NumberSequence.new(1, 1)
end)

script.Parent.Unequipped:Connect(function()
	script.Parent.Equipado.Value = false
	idle:Stop(); equipped = false
	Humanoid.WalkSpeed = 4
	poner:Play()
	script.Sounds.Poner:Play()
	wait(1)
	Humanoid.WalkSpeed = 16
end)


local InCombo = false
local ComboStep = 0 

local avaibleAttackAnimations = {7292031028, 7289385180, 7305181383} 

local animationn = Instance.new("Animation", player.Character) 
animationn.Name = "AttackAnimation" 
animationn.AnimationId = "rbxassetid://"..tostring(7292031028) 

local animation22 = Instance.new("Animation", player.Character) 
animation22.Name = "AttackAnimation" 
animation22.AnimationId = "rbxassetid://"..tostring(7289385180) 

local animation33 = Instance.new("Animation", player.Character) 
animation33.Name = "AttackAnimation" 
animation33.AnimationId = "rbxassetid://"..tostring(7305181383) 

local animation = Character.Humanoid:LoadAnimation(animationn)
local animation2 = Character.Humanoid:LoadAnimation(animation22)
local animation3 = Character.Humanoid:LoadAnimation(animation33)

function combo()
	ComboStep = ComboStep + 1
	script.Attack:FireServer()
	script.Sounds.noToca:Play()
	Trail.Transparency = NumberSequence.new(0.9)
	Humanoid.WalkSpeed = 4
	CanAttack = false
	animation:Play()
	wait(0.5)
	if equipped == true then idle:Play() end -- check bool
	CanAttack = true

end


function combo2()
	ComboStep = ComboStep + 1
	script.Attack:FireServer()
	script.Sounds.noToca:Play()
	Trail.Transparency = NumberSequence.new(0.9)
	Humanoid.WalkSpeed = 4
	CanAttack = false
	animation2:Play()
	wait(0.5)
	if equipped == true then idle:Play() end -- check bool
	CanAttack = true

end


function combo3()
	ComboStep = ComboStep + 1
	script.Attack:FireServer()
	script.Sounds.noToca:Play()
	Trail.Transparency = NumberSequence.new(0.9)
	Humanoid.WalkSpeed = 4
	CanAttack = false
	animation3:Play()
	wait(0.5)
	if equipped == true then idle:Play() end -- check bool
	CanAttack = true
	Humanoid.WalkSpeed = 16
	ComboStep = 0
	InCombo = false
end

script.Parent.Activated :Connect(function()
	if CanAttack == true and player.Character.CanDamage.Value == true and Character.IsBlocking.Value == 0 then

		if InCombo then
			if ComboStep == 1 then
				print(1)
				delay(0.5,combo)
				
			end
			
			if ComboStep == 2 then
				print(2)
				delay(0.5 ,combo2)
			end
			
			if ComboStep == 3 then
				print(3)
				delay(0.5,combo3)
			end
		else -- start combo
			ComboStep = 1
			InCombo = true
			script.Attack:FireServer()
			script.Sounds.noToca:Play()
			Trail.Transparency = NumberSequence.new(0.9)
			Humanoid.WalkSpeed = 4
			CanAttack = false
			wait(0.5)
			Trail.Transparency = NumberSequence.new(1)
			wait(0.5)
			if equipped == true then idle:Play() end -- check bool
			CanAttack = true
			Humanoid.WalkSpeed = 16
		end

	end
	
end)

Character.Humanoid.Running:Connect(function(speed)
	if speed > 4 and script.Parent.Equipado.Value == true then
		idle:Stop()
		run:Play()
	elseif speed == 0 and script.Parent.Equipado.Value == true then
		run:Stop()
		idle:Play()
		
	elseif script.Parent.Equipado.Value == false then
		run:Stop()
		idle:Stop()	
	end

end)

Like DJ suggested in the top was my old post but i did find a better way of playing different animations in a order

local Anim = --- Here
local Anim2 = --- Here
local Order = 1

function AttackAnimLoader()
    --- Do functions here
    --- Also reset combo here if not in it
    if Order == 1 then
        Anim:Play()
        Order = Order + 1 
        return
    end
    if Order == 2 then
        Anim:Play()
        Order = 1
        return
    end
end

Here is another option for doing animations

my way of doing combos

local Combo: Number, MaxCombo: Number = 0, 0
--- MaxCombo Checker
for i, Content in pairs(script:WaitForChild("Animations", 0.1):GetChildren()) do
	if Content.Name:match("Attack") then 
		MaxCombo += 1
	end
end

function AttackAnimLoader()
	if Cooldown == true then return end
	Combo += 1
	if Combo >= MaxCombo + 1 then Combo = 1 return end
	Cooldown = true
	local ComboAnimation = Character.Humanoid:LoadAnimation(script.Animations["Attack" .. Combo])
	ComboAnimation:Play()
	ComboAnimation:GetMarkerReachedSignal("Activate"):Connect(function(Parameter)
		-- Code
	end)
	ComboAnimation.Stopped:Wait()
	Cooldown = false
end