How to create a stun cooldown for combat system?

Hello guys and happy new year🎉.

I’ve been working on a fighting game for weeks, and I realized I needed a stun system for my combat script. What I wanted was a system where players that get hit by some hitbox ( stun system happens through a hitbox.touched event ) get a boolean attribute set to true named “stunned” on their humanoid, and after some time ( the stun cooldown ), this value would be set to false to indicate that the player hit is no longer stunned.

I have tried to use delay()

local hitbox = Instance.new("Part")
local hit = false
local Stuncooldown = 0.9
hitbox.Touched:Connect(function(parttouched)
	
	if parttouched.Parent ~= Player.Character and not hit then
		
		--hitbox properties
		hitbox.Anchored = true
		hitbox.Material = Enum.Material.Neon
		hitbox.Color = Color3.new(1, 0, 0)
		
		if parttouched.Parent:FindFirstChildOfClass("Humanoid") then

			local humanoidenemy = parttouched.Parent:FindFirstChildOfClass("Humanoid")
                        --if plr gets hit while being stun or not
			if parttouched.Parent.Humanoid:GetAttribute("stunned") == true then
				print("player was stun")
			else
				print("player was not stun")
			end

			hit = true

			-- stun system
			
			humanoidenemy:SetAttribute("stunned", true)
			delay(Stuncooldown ,function()
				humanoidenemy:SetAttribute("stunned",false)
			end)

			parttouched.Parent.Humanoid.Health = parttouched.Parent.Humanoid.Health - 5
			hitbox:Destroy()

		end 
	end
end)

So every time a player gets hit, its humanoid would get a “stunned” attribute set to true but if he gets hit like 5 multiple times and at different times within the stun cooldown, the “stunned” attribute would be set to false after the cooldown for each time he got hit, which is what i’m trying to avoid here ( but i don’t know how to).

i know it looks complicated but does anyone got any idea how to fix this? thank you.

delay() is deprecated and should be Replaced with task.delay()

plus, you aren’t using delay() correctly here, It will only delay the code inside it, not the code outside it

thanks for the info, i replaced delay() with task.delay(),
but actualy the only thing i need to delay is the stun attribute change, everything outside the delay must be done the moment the player gets touched.

Actually, I just happen to find a solution to my problem so in case anyone is interested i’m goin to try to explain it:
here is the code, if it helps somehow

local hitbox = Instance.new("Part")
local hit = false
local Stuncooldown = 0.9

-- canchangestun originaly set to true

local canchangestun = true

-- when a plr gets hit by hitbox

hitbox.Touched:Connect(function(parttouched)

	if parttouched.Parent ~= Player.Character and not hit then

		--hitbox properties
		hitbox.Anchored = true
		hitbox.Material = Enum.Material.Neon
		hitbox.Color = Color3.new(1, 0, 0)

		if parttouched.Parent:FindFirstChildOfClass("Humanoid") then

			local humanoidenemy = parttouched.Parent:FindFirstChildOfClass("Humanoid")
			--if plr gets hit while being stun or not
			if parttouched.Parent.Humanoid:GetAttribute("stunned") == true then
				print("player was stun")
			else
				print("player was not stun")
			end

			hit = true

			-- setting plr stun attribute to true because he got hit 

			humanoidenemy:SetAttribute("stunned", true)
			
			-- changing stunnedsignal attribute because it's supposed to be a signal
			
			humanoidenemy:SetAttribute("stunnsignal",not humanoidenemy:GetAttribute("stunnsignal"))

			parttouched.Parent.Humanoid.Health = parttouched.Parent.Humanoid.Health - 5
			hitbox:Destroy()
			
			--the stun cooldown system
			
			--when the humanoid stunnedsignal value is changed ( when every plr spawns, this value is set to true )
			humanoidenemy.AttributeChanged:Connect(function(str)

				if str == "stunnedsignal" then

					if humanoidenemy:GetAttribute("stunned") == true then
						print("changed")
						canchangestun = false
						return
					end
				end
			end)
			
			task.wait(Stuncooldown)
			
			if canchangestun == true then
			humanoidenemy:SetAttribute("stunned",false)
			end 
			
		end 
	end
end)

So basically, what i did was that i added another boolean attribute called “stunnsignal” to the plr that got hit, then i added a “canchangestun” boolean variable ( in the script ) that is originaly set to true, and i inplemented another event at the end of the hitbox.touched event, that fires each time the “stunnsignal” attribute is changed, followed by a task.wait( stunncooldown ) right after the event.

So when the plr gets hit by hitbox, this event fires a function and inside that function there is another event which sets the “canchangestun” variable to false each time ( within the stuncooldown time ) the plr’s “stunnsignal” attribute is changed ( set to its opposite value ). and if after waiting the stuncooldown time, if the " canchangestun " variable is still set to true then the plr hit will be no longer stun after that stuncooldown, and it works fine with me

1 Like

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