Most practical way to cancel attacks?

I’m making a game where there are attacks that have wait()s in them, and i was wondering: what is the best way to check and cancel a move when for example the player dies, or gets stunned while attacking?
My first idea was just spamming “if dead then --[[cancel stuff]] return end”, but maybe there is a secret that i’m missing out on and haven’t figured out yet, if you know this please share!

Hi! The first thing that comes to mind is the concept of defining an attack. Once you figure that out, then to cancel an attack is to simply remedy the effects of an attack. For example.

For example: Attack 1 (Sword Slash)

Suppose the Sword Slash attack takes 10 stamina and does 25 damage. We can first check cost and deduct the 10 stamina.

Define a cancel period (before damage is given is probably the cleanest), where the player has the option to cancel the attack. If it is canceled, then simply return the stamina, and return. I personally, would have a couple bools, since coding wise its cleaner for me. So taking your example, I would have an isDead and isStunned bool, then once it is damage feedback time, you only need one if statement with the condition if not isDead and not isStunned.

Hope this helps!

TLDR: start of attack → cancel period → damage feedback (you can use bools, followed by one if statement)

1 Like

Usually there’s two reasons an attack is cancelled, either because another attack was used or the user was stunned/killed. So first, you have to write a function that checks both of those (or any other conditions you add) and then returns true or false.

Then, whenever a wait() happens during an attack, use this:

if AbleToDoStuff() == false then
	return 
end

which can be condensed to:

if AbleToDoStuff() == false then return end
1 Like

You can put the player’s attack in a thread, and when you wan’t to cancel the attack you can check if the Threads[player] isnt nil, if its not nil, you can task.cancel(Threads[player])

An example:

local Threads = {}

local function Attack(player, ... : any)
	Threads[player] = task.spawn(function()
		-- your code
	end)
end

---- optional cleanup function ------
local function CleanupAttack(player)
	for _, instance in workspace.Effects[player]:GetChildren() do
		instance:Destroy()
	end
end
-------------------

local function CancelAttack(player,)
	local playerThread = Threads[player]
	if not playerThread then return end
	if coroutine.status(playerThread) ~= "running" then return end
	task.cancel(playerThread)
     -- your code
end

this will cancel the player’s attack immediately
its not the best code, but enough to give you an idea of how you can cancel an attack

I suggest reading about coroutines & the task library: coroutine | Documentation - Roblox Creator Hub | task | Documentation - Roblox Creator Hub

1 Like

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