How do I make a stacking stun system?

I’m making a fighting game based off of atla, and one of the core principles will be small combos.

In the past my stun system has worked fine, but now when working on abilities with combos in mind, it hasnt fit the games needs right.

When someone is stunned for a bit with repeated attacks, they come unstunned which is NOT helpful (not intentional)

I use a module for the stun so yeah. Heres the stun piece of my module:

function main_combat.stun(plr:Character, lifetime:optional)
	if players[plr] then
		if lifetime == nil then
			plr.HumanoidRootPart.AssemblyLinearVelocity = Vector3.new(0, 0, 0)
			players[plr]['stunned'] = true
			plr.Humanoid.WalkSpeed = 0
			plr.Humanoid.JumpHeight = 0
		else
			plr.HumanoidRootPart.AssemblyLinearVelocity = Vector3.new(0, 0, 0)
			plr.Humanoid.WalkSpeed = 0
			plr.Humanoid.JumpHeight = 0
			
			if players[plr]['stunned_lifetime'] > 0 then
				players[plr]['stunned_lifetime'] = tonumber(string.format("%0.1f", (os.clock() - players[plr]['prev_stun_t']) + lifetime))
			else
				players[plr]['stunned_lifetime'] = lifetime
			end

			local t = os.clock()
			players[plr]['prev_stun_t'] = tonumber(t)
			
			players[plr]['stunned'] = true
			
			while wait(0.01) do
				if os.clock() - t > players[plr]['stunned_lifetime'] + 0.1 then
					players[plr]['stunned'] = false
					players[plr]['stunned_lifetime'] = 0
					players[plr]['prev_stun_t'] = nil
					plr.Humanoid.WalkSpeed = players[plr]['walkspeed']
					plr.Humanoid.JumpHeight = players[plr]['jumpheight']
					
					local ff = Instance.new("ForceField")
					ff.Visible = false
					ff.Parent = plr
					game.Debris:AddItem(ff, 0.1)
					return
				end
			end
		end
	end
end

I need the stun to ignore past stuns, and instantly stun for the duration of the newest attack.

Any help would be appreciated, thanks.

I’m not completely sure what you’re trying to do here, or why it is so complicated but.

The while loop in your module might be the issue. Having a wait() inside a module will pause the module until that wait() is over, because your module is constantly being paused: any new stuns can’t be applied until the previous one has gone away (and returned, breaking the wait(0.01) while loop).

I would suggest looking into spawn or coroutines.

Hope this helps.

It’s easy, you just need to have a value you update every time stun is changed to check if the target was stunned again.

StunCount = 1 
IsStunned = false

function beStunned(StunStuff)
 	--//Each time this function is called, StunCount is updated.
	--//So if it's called again, c_StunCount will be different than the script-wide StunCount.
	local c_StunCount = StunCount + 1
	StunCount = c_StunCount

	IsStunned = true

	--//I'd imagine you wouldn't want this to halt the function, so this is task.delay'd
	task.delay(StunStuff.Time,function()
		
		--//If StunCount hasn't been changed, we haven't been stunned again.
		if c_StunCount == StunCount then
			IsStunned = false
		end
	end)
end
1 Like