Why is this attack combo sequence script not working properly?

  1. What do you want to achieve? I’m working on a simple combo sequence script, with 3 different attacks. If the player waits too long to attack again (>1 second), the combo sequence restarts back to the first attack, otherwise it moves on the second and eventually third. Once the third attack is reached, the counter resets back to 1.

  2. What is the issue? The “cooldown limit” doesn’t work for some reason; even if i wait 10 seconds before the first and second attack, or the second and the third, the counter doesn’t reset back to 1, it just moves onto the next attack as if i did it before the 1 second limit.

  3. What solutions have you tried so far? I tried tweaking the code, and nothing seems to work as intended. It never resets if i wait too long.

Local Script:

local Player = game:GetService("Players").LocalPlayer
local Mouse = Player:GetMouse()
local UIS = game:GetService("UserInputService")

local counter = 0
local lastUsed = 0
local cd = 1

UIS.InputBegan:Connect(function(input,isTyping)
	if isTyping then return end

	if input.UserInputType == Enum.UserInputType.MouseButton1 then
		if lastUsed - tick() < cd then
			lastUsed = tick()
			print("before: "..counter)
			counter += 1
			print("after: "..counter)
			if counter > 3 then
				counter = 1
			end
			game:GetService("ReplicatedStorage"):FindFirstChild("RemoteEvent"):FireServer(counter,Mouse.Hit.Position)
		else
			counter = 1
			print("too much time")
			game:GetService("ReplicatedStorage"):FindFirstChild("RemoteEvent"):FireServer(counter,Mouse.Hit.Position)
		end
	end
end)

The script fires a remote event to the server, and based on the number it sends, it plays the matching animation. That parts works fine, I just can’t seem to get it to reset after the time limit.

The code which resets only runs on input began which is the issue.

To make a proper combo reset one needs another method to run code when the time is up. To do this personally I have used a timer module like here:

Hey thank you so much! I read the documentation and came up with this:

local comboResetTimer -- store the previous start punching timer

UIS.InputBegan:Connect(function(input,isTyping)
	if isTyping then return end
	
	if input.UserInputType == Enum.UserInputType.MouseButton1 then
		Remote:FireServer(counter,Mouse.Hit.Position)
		if comboResetTimer and comboResetTimer.IsRunning then
			comboResetTimer:Reset()
			counter += 1
			if counter > 3 then
				counter = 1
			end
		else
			comboResetTimer = Timer.new(cd)
			comboResetTimer.Completed:Connect(function()
				counter = 1
			end)
			comboResetTimer:Start()
			--Remote:FireServer(counter,Mouse.Hit.Position)
		end
	end
end)

Unfortunately it doesn’t seem to work at all now…? No errors, it simply won’t play the animations, as if the Remote was unable to be fired.

Sorry for bump, but I still haven’t found a solution… ^^"

Try somethings like the below. Its a local script inside of StarterGui.

-- Services --
local UIS = game:GetService("UserInputService");
local RSS = game:GetService("RunService");

-- Variables --
local ComboChain = 0; -- The last Combo chain
local LastAttackTick = 0; -- The last tick() when the player clicked

-- Settings --
local AttackChainResetThreshold = 0.5; -- The amount of time between clicks before the attack chain resets

-- Main Function --
function ClickAttack()
	local Tick = RSS.Stepped:Wait(); 
	if Tick - LastAttackTick < AttackChainResetThreshold then -- Check if they clicked within the AttackChainResetThreshold value
		if ComboChain == 1 then -- If combo is attack 1, then move onto attack 2
			print("Slash 2");
			ComboChain = 2;
		elseif ComboChain == 2 then -- If combo is attack 2, then move onto attack 3
			print("Slash 3");
			ComboChain = 3;
		elseif ComboChain == 3 then -- If combo is attack 3, reset and back to attack 1
			print("Slash 1")
			ComboChain = 1;
		end;
	else -- If the player didn't click again within the threshold, go back to the default attack (which is attack 1)
		print("Default Slash 1");
		ComboChain = 1;
	end;
	LastAttackTick = Tick;
end;

-- UserInput Functions --
UIS.InputBegan:Connect(function(InputObject, GameProcessedEvent) 
	if not GameProcessedEvent then
		if InputObject.UserInputType == Enum.UserInputType.MouseButton1 or InputObject.UserInputType == Enum.UserInputType.Touch then
			ClickAttack();
		end;
	end;
end);

4 Likes