Stun ending shorter than its supposed to be

Hello, im making a combat system and want to add in stun

Problem is, when hitting someone, it auto unstuns them after a second, but if you hit them again, the other cooldown still goes meaning that the stun lasts shorter than its supposed to be.

heres the code

local Main = {}

local soundmodule = require(game.ReplicatedStorage.Modules.SoundModule)
local rag = require(game.ReplicatedStorage.Modules.RagdollModule)
local hitbox_folder = Instance.new("Folder",workspace)
local hitparticle = workspace.HitParticle
hitbox_folder.Name = "HitboxFolder"

local DATA_Template = {
	["DMG"] = 0,
	["Size"] = Vector3.new(0,0,0),
	["Offset"] = CFrame.new(0,0,0),
	["Ragdoll"] = false,
	["Knockback"] = Vector3.new(0,0,0)
}

function Main.AutoDelete(item,length)
	task.delay(length,function()
		item:Destroy()
	end)
end

function Main.AddIFrames(char)
	local IFrames = Instance.new("StringValue",char)
	IFrames.Name = "IFrames"
	Main.AutoDelete(IFrames,0.08)
end

function Main.StopAllAnims(char)
	for _,v in pairs(char.Humanoid.Animator:GetPlayingAnimationTracks()) do
		v:Stop()
	end
end

function Main.CheckHit(char,hitbox : Part,DATA)
	local partsInHitbox = workspace:GetPartsInPart(hitbox)
	local hitSmth = false
	
	local function hitboxFunc(part)
		if part.Parent:FindFirstChild("Humanoid") and not part.Parent:FindFirstChild("IFrames") then
			local enemyChar = part.Parent
			local enemyHum : Humanoid = enemyChar:FindFirstChild("Humanoid")
			if enemyChar == char then return end
			if enemyHum.Health <= 0 then return end
			if DATA.DMG == 0 then return end
			local randomStun = math.random(1,3)
			local randomAnim = game.ReplicatedStorage.Animations.Stun[randomStun]
			local animTrack = enemyHum.Animator:LoadAnimation(randomAnim)
			Main.StopAllAnims(enemyChar)
			animTrack:Play(0)
			hitSmth = true
			enemyHum:TakeDamage(DATA.DMG)
			hitparticle.CFrame = enemyChar.HumanoidRootPart.CFrame
			hitparticle.A.A:Emit(1)
			hitparticle.A.B:Emit(1)
			soundmodule.Create(enemyChar,game.SoundService.M1s.Punch)
			Main.AddIFrames(enemyChar)
			enemyChar:SetAttribute("Stunned",true)
			task.delay(1,function()
				enemyChar:SetAttribute("Stunned",false)
			end)
			if DATA.Ragdoll then
				rag.Start(enemyChar)
				task.delay(2,function()
					rag.Stop(enemyChar)
				end)
			end
		end
	end
	for _,part in pairs(partsInHitbox) do
		hitboxFunc(part)
	end
	hitbox:Destroy()
	return hitSmth
end

function Main.Create(char, DATA)
	local hitbox = Instance.new("Part",hitbox_folder)
	hitbox.Name = char.Name
	hitbox.Size = DATA.Size
	hitbox.CanCollide = false
	hitbox.Anchored = false
	hitbox.Massless = true
	hitbox.Transparency = 0.8
	hitbox.CFrame = char:FindFirstChild("HumanoidRootPart").CFrame * DATA.Offset
	local weld = Instance.new("WeldConstraint",hitbox)
	weld.Part0 = char:WaitForChild("HumanoidRootPart")
	weld.Part1 = hitbox
	--Main.AutoDelete(hitbox,DATA.Linger)
	if DATA.DMG == 0 then
		return Main.CheckHit(char,hitbox,DATA)
	else
		Main.CheckHit(char,hitbox,DATA)
	end
end

return Main

You can create a table in the module with the key-value pairs being character : stun task, and then when a character is hit you can lookup the character in the table, and if it is found you can call task.cancel on the task, and overwrite it with a new one. Example:

local charStuns = {}

In the hit function:

enemyChar:SetAttribute("Stunned",true)
if charStuns[enemyChar] then
    task.cancel(charStuns[enemyChar])
end
charStuns[enemyChar] = task.spawn(function()
    task.wait(1)
    enemyChar:SetAttribute("Stunned",false)
    charStuns[enemyChar] = nil
end)
1 Like

would i do table.insert(charStuns,enemychar) after setting it to true?

you need to have some reference to the task so that you can cancel it if they are hit again early. do this after setting it to true

edit: i made a mistake in the code i have corrected it now

thank you so much! I didnt even know that task.cancel existed

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