Stacking Task.Spawn Tweens

Im trying to make a effect when someone is killed. Everything is good about the script until you kill more then one player before the task.wait is ended. If that happens then it stacks the task.wait and makes everything faster? Can someone help?

local d = true
local btn = script.Parent.Frame

local RunServ = game:GetService("RunService")
local Pos = script.Parent.Frame.Position
local plr = game.Players.LocalPlayer

local function east()
	btn.Size = UDim2.new({0.032, 0},{0.011, 0}) 
	btn.Visible = true
	btn:TweenSize(UDim2.new(0.443, 0,0.156, 0), Enum.EasingDirection.Out, Enum.EasingStyle.Quint, 0.175, true)
	local gyat = game.Players.LocalPlayer.folder.lastkilled
	btn.Killed.Text = "Killed "..gyat.Value
	btn.item.Text = "Gun Kill!"
	

	local random = math.random(1,900)
	local xnew = random/1000
	local new = game.ReplicatedStorage.Money:Clone()
	new.Parent = script.Parent
	new.Position = UDim2.new(xnew,0,1,0)
	
	if game.Players.LocalPlayer.folder.killstreak.Value < 2 then
		btn.KillStreak.Visible = false
		new.TextLabel.Text = "+5"
		game.ReplicatedStorage.MoneyAmt.Five:FireServer(plr)
	end
	if game.Players.LocalPlayer.folder.killstreak.Value == 2 then
		btn.KillStreak.Visible = true
		btn.KillStreak.Text = "DOUBLE"
		new.TextLabel.Text = "+10"
		game.ReplicatedStorage.MoneyAmt.Ten:FireServer(plr)
	end
	if game.Players.LocalPlayer.folder.killstreak.Value == 3 then
		btn.KillStreak.Visible = true
		btn.KillStreak.Text = "TRIPPLE"
		new.TextLabel.Text = "+20"
		game.ReplicatedStorage.MoneyAmt.Twenty:FireServer(plr)
	end
	if game.Players.LocalPlayer.folder.killstreak.Value == 4 then
		btn.KillStreak.Visible = true
		btn.KillStreak.Text = "QUAD"
		new.TextLabel.Text = "+30"
		game.ReplicatedStorage.MoneyAmt.Thirty:FireServer(plr)
	end
	if game.Players.LocalPlayer.folder.killstreak.Value == 5 then
		btn.KillStreak.Visible = true
		btn.KillStreak.Text = "ACE"
		new.TextLabel.Text = "+40"
		game.ReplicatedStorage.MoneyAmt.Fourty:FireServer(plr)
	end
	if game.Players.LocalPlayer.folder.killstreak.Value >= 6 then
		btn.KillStreak.Visible = true
		btn.KillStreak.Text = "MULTI"
		new.TextLabel.Text = "+50"
		game.ReplicatedStorage.MoneyAmt.Fifty:FireServer(plr)
	end
	
	
	RunServ.RenderStepped:Connect(function(dt)
		local BobbleX =  math.abs(math.cos(os.clock() * 50) * 0.001) 
		local BobbleY = math.abs(math.sin(os.clock() * 20) * 0.001) 
		btn.Position = Pos + UDim2.new(BobbleX,0,BobbleY,0) 
	end)

	wait(1.5)
	
	
	btn:TweenSize(UDim2.new({0.032, 0},{0.011, 0}), Enum.EasingDirection.InOut, Enum.EasingStyle.Quint, 0.175, true)
end

game.ReplicatedStorage.Killed.OnClientEvent:Connect(function(player)
	game.SoundService.DingSound:Play()
	task.spawn(east)
end)

Here is a video:

Is there a way for you to wait until the effect is done and once it is it fires the next?

Did you try use some video from YouTube or some AI?

Try cloning the GUI and tweening the clone; Since you are not cloning / generating a new GUI each time the function is called, it will cause issues. Since you have a second function trying to tween the same GUI at the same time it will cause issues.

The issue you’re encountering happens because the task.wait in your script is not being synchronized properly when multiple players are killed before the wait(1.5) ends. Each time east() is called (on a kill event), a new wait cycle is started. However, when multiple kills happen in quick succession, it results in multiple task.wait cycles running concurrently, which causes the TweenSize to speed up and stack.

To fix this, you can use a flag (or variable) to ensure that only one east() function runs at a time and to delay new function calls until the previous one has finished.

  1. isProcessing flag: This ensures that the east() function does not run concurrently. When isProcessing is true, it prevents the function from running again until the previous one finishes.
  2. Early return in east(): Before proceeding with the effect, the script checks if isProcessing is true. If it is, the function will return early and won’t run the effect again until the previous one is finished.
    3. Reset the flag: After the wait(1.5) delay, the flag isProcessing is set back to false so that another kill can trigger the effect properly.

This should fix the issue of stacking the task.wait and causing the effect to run faster.
- - > AI (don’t make it like solution)

like try maybe this one:

local d = true
local btn = script.Parent.Frame
local RunServ = game:GetService("RunService")
local Pos = script.Parent.Frame.Position
local plr = game.Players.LocalPlayer

local isProcessing = false -- Flag to check if effect is still running

local function east()
    if isProcessing then return end -- If already processing, exit the function
    isProcessing = true -- Set the flag to true to prevent further calls
    
    btn.Size = UDim2.new({0.032, 0},{0.011, 0}) 
    btn.Visible = true
    btn:TweenSize(UDim2.new(0.443, 0,0.156, 0), Enum.EasingDirection.Out, Enum.EasingStyle.Quint, 0.175, true)
    local gyat = game.Players.LocalPlayer.folder.lastkilled
    btn.Killed.Text = "Killed "..gyat.Value
    btn.item.Text = "Gun Kill!"
    
    local random = math.random(1,900)
    local xnew = random/1000
    local new = game.ReplicatedStorage.Money:Clone()
    new.Parent = script.Parent
    new.Position = UDim2.new(xnew,0,1,0)
    
    if game.Players.LocalPlayer.folder.killstreak.Value < 2 then
        btn.KillStreak.Visible = false
        new.TextLabel.Text = "+5"
        game.ReplicatedStorage.MoneyAmt.Five:FireServer(plr)
    end
    if game.Players.LocalPlayer.folder.killstreak.Value == 2 then
        btn.KillStreak.Visible = true
        btn.KillStreak.Text = "DOUBLE"
        new.TextLabel.Text = "+10"
        game.ReplicatedStorage.MoneyAmt.Ten:FireServer(plr)
    end
    if game.Players.LocalPlayer.folder.killstreak.Value == 3 then
        btn.KillStreak.Visible = true
        btn.KillStreak.Text = "TRIPPLE"
        new.TextLabel.Text = "+20"
        game.ReplicatedStorage.MoneyAmt.Twenty:FireServer(plr)
    end
    if game.Players.LocalPlayer.folder.killstreak.Value == 4 then
        btn.KillStreak.Visible = true
        btn.KillStreak.Text = "QUAD"
        new.TextLabel.Text = "+30"
        game.ReplicatedStorage.MoneyAmt.Thirty:FireServer(plr)
    end
    if game.Players.LocalPlayer.folder.killstreak.Value == 5 then
        btn.KillStreak.Visible = true
        btn.KillStreak.Text = "ACE"
        new.TextLabel.Text = "+40"
        game.ReplicatedStorage.MoneyAmt.Fourty:FireServer(plr)
    end
    if game.Players.LocalPlayer.folder.killstreak.Value >= 6 then
        btn.KillStreak.Visible = true
        btn.KillStreak.Text = "MULTI"
        new.TextLabel.Text = "+50"
        game.ReplicatedStorage.MoneyAmt.Fifty:FireServer(plr)
    end
    
    RunServ.RenderStepped:Connect(function(dt)
        local BobbleX = math.abs(math.cos(os.clock() * 50) * 0.001) 
        local BobbleY = math.abs(math.sin(os.clock() * 20) * 0.001) 
        btn.Position = Pos + UDim2.new(BobbleX,0,BobbleY,0) 
    end)

    -- Wait for the effect to complete
    wait(1.5)
    
    btn:TweenSize(UDim2.new({0.032, 0},{0.011, 0}), Enum.EasingDirection.InOut, Enum.EasingStyle.Quint, 0.175, true)
    
    -- Reset the flag to allow the next effect
    isProcessing = false
end

game.ReplicatedStorage.Killed.OnClientEvent:Connect(function(player)
    game.SoundService.DingSound:Play()
    task.spawn(east) -- Run the effect in a separate task to prevent blocking
end)


The problem with this is while the debounce is active and I kill something It does not stack the effect, which I would like.

I got the shaking from another forum thats it though

If I do that then it will show 2 at the same time

Did you try that I wrote?
If no, try or use some ai to find solution in this issue

i did, all it did was a debounce, I will try ai

local d = true
local btn = script.Parent.Frame
local RunServ = game:GetService("RunService")
local Pos = script.Parent.Frame.Position
local plr = game.Players.LocalPlayer
local effectQueue = {} -- Table to store ongoing effects for spacing

local function east()
    -- If there are any ongoing effects, space out the new effect
    local offset = #effectQueue * 0.25  -- Adjust this to control how spaced out the effects are
    local effect = {}
    table.insert(effectQueue, effect) -- Add this effect to the queue
    
    -- Set initial position and size for the button
    btn.Size = UDim2.new(0.032, 0, 0.011, 0)
    btn.Visible = true
    btn:TweenSize(UDim2.new(0.443, 0, 0.156, 0), Enum.EasingDirection.Out, Enum.EasingStyle.Quint, 0.175, true)
    local gyat = game.Players.LocalPlayer.folder.lastkilled
    btn.Killed.Text = "Killed "..gyat.Value
    btn.item.Text = "Gun Kill!"

    local random = math.random(1,900)
    local xnew = random / 1000
    local new = game.ReplicatedStorage.Money:Clone()
    new.Parent = script.Parent
    new.Position = UDim2.new(xnew, 0, 1, 0)

    if game.Players.LocalPlayer.folder.killstreak.Value < 2 then
        btn.KillStreak.Visible = false
        new.TextLabel.Text = "+5"
        game.ReplicatedStorage.MoneyAmt.Five:FireServer(plr)
    end
    if game.Players.LocalPlayer.folder.killstreak.Value == 2 then
        btn.KillStreak.Visible = true
        btn.KillStreak.Text = "DOUBLE"
        new.TextLabel.Text = "+10"
        game.ReplicatedStorage.MoneyAmt.Ten:FireServer(plr)
    end
    if game.Players.LocalPlayer.folder.killstreak.Value == 3 then
        btn.KillStreak.Visible = true
        btn.KillStreak.Text = "TRIPPLE"
        new.TextLabel.Text = "+20"
        game.ReplicatedStorage.MoneyAmt.Twenty:FireServer(plr)
    end
    if game.Players.LocalPlayer.folder.killstreak.Value == 4 then
        btn.KillStreak.Visible = true
        btn.KillStreak.Text = "QUAD"
        new.TextLabel.Text = "+30"
        game.ReplicatedStorage.MoneyAmt.Thirty:FireServer(plr)
    end
    if game.Players.LocalPlayer.folder.killstreak.Value == 5 then
        btn.KillStreak.Visible = true
        btn.KillStreak.Text = "ACE"
        new.TextLabel.Text = "+40"
        game.ReplicatedStorage.MoneyAmt.Fourty:FireServer(plr)
    end
    if game.Players.LocalPlayer.folder.killstreak.Value >= 6 then
        btn.KillStreak.Visible = true
        btn.KillStreak.Text = "MULTI"
        new.TextLabel.Text = "+50"
        game.ReplicatedStorage.MoneyAmt.Fifty:FireServer(plr)
    end

    -- Use RenderStepped for continuous shaking
    local shakeStartTime = tick()
    RunServ.RenderStepped:Connect(function(dt)
        local elapsed = tick() - shakeStartTime
        local BobbleX = math.abs(math.cos(elapsed * 50) * 0.001)
        local BobbleY = math.abs(math.sin(elapsed * 20) * 0.001)
        btn.Position = Pos + UDim2.new(BobbleX, 0, BobbleY, 0)
    end)

    -- After effect time, remove it from the queue and reset size
    wait(1.5)

    -- Remove this effect from the queue
    table.remove(effectQueue, 1)

    -- Once the effect finishes, revert the button size
    btn:TweenSize(UDim2.new(0.032, 0, 0.011, 0), Enum.EasingDirection.InOut, Enum.EasingStyle.Quint, 0.175, true)
end

game.ReplicatedStorage.Killed.OnClientEvent:Connect(function(player)
    game.SoundService.DingSound:Play()
    task.spawn(east)  -- Start the effect independently for each kill
end)

?

Don’t task.spawn. The clientEvent is already putting it in its own task and what you actually want is sequential behavior. Loop through a list removing everything as you go. Then fade once all of the functions have finished (including the waits). Blocking is very much intended behavior here.

local d = true
local btn = script.Parent.Frame
local RunServ = game:GetService("RunService")
local Pos = script.Parent.Frame.Position
local plr = game.Players.LocalPlayer

local isProcessing = false -- Flag to check if effect is still running

local function east(gyat)
    if isProcessing then return end -- If already processing, exit the function
    isProcessing = true -- Set the flag to true to prevent further calls
    
    btn.Size = UDim2.new({0.032, 0},{0.011, 0}) 
    btn.Visible = true
    btn:TweenSize(UDim2.new(0.443, 0,0.156, 0), Enum.EasingDirection.Out, Enum.EasingStyle.Quint, 0.175, true)
    btn.Killed.Text = "Killed ".. gyat
    btn.item.Text = "Gun Kill!"
    
    local random = math.random(1,900)
    local xnew = random/1000
    local new = game.ReplicatedStorage.Money:Clone()
    new.Parent = script.Parent
    new.Position = UDim2.new(xnew,0,1,0)
    
    if game.Players.LocalPlayer.folder.killstreak.Value < 2 then
        btn.KillStreak.Visible = false
        new.TextLabel.Text = "+5"
        game.ReplicatedStorage.MoneyAmt.Five:FireServer(plr)
    end
    if game.Players.LocalPlayer.folder.killstreak.Value == 2 then
        btn.KillStreak.Visible = true
        btn.KillStreak.Text = "DOUBLE"
        new.TextLabel.Text = "+10"
        game.ReplicatedStorage.MoneyAmt.Ten:FireServer(plr)
    end
    if game.Players.LocalPlayer.folder.killstreak.Value == 3 then
        btn.KillStreak.Visible = true
        btn.KillStreak.Text = "TRIPPLE"
        new.TextLabel.Text = "+20"
        game.ReplicatedStorage.MoneyAmt.Twenty:FireServer(plr)
    end
    if game.Players.LocalPlayer.folder.killstreak.Value == 4 then
        btn.KillStreak.Visible = true
        btn.KillStreak.Text = "QUAD"
        new.TextLabel.Text = "+30"
        game.ReplicatedStorage.MoneyAmt.Thirty:FireServer(plr)
    end
    if game.Players.LocalPlayer.folder.killstreak.Value == 5 then
        btn.KillStreak.Visible = true
        btn.KillStreak.Text = "ACE"
        new.TextLabel.Text = "+40"
        game.ReplicatedStorage.MoneyAmt.Fourty:FireServer(plr)
    end
    if game.Players.LocalPlayer.folder.killstreak.Value >= 6 then
        btn.KillStreak.Visible = true
        btn.KillStreak.Text = "MULTI"
        new.TextLabel.Text = "+50"
        game.ReplicatedStorage.MoneyAmt.Fifty:FireServer(plr)
    end
    
    RunServ.RenderStepped:Connect(function(dt)
        local BobbleX = math.abs(math.cos(os.clock() * 50) * 0.001) 
        local BobbleY = math.abs(math.sin(os.clock() * 20) * 0.001) 
        btn.Position = Pos + UDim2.new(BobbleX,0,BobbleY,0) 
    end)

    -- Wait for the effect to complete
    wait(1.5)
    
    -- Reset the flag to allow the next effect
    isProcessing = false
end

local looping = false
local effects = {}
game.ReplicatedStorage.Killed.OnClientEvent:Connect(function(player)
    game.SoundService.DingSound:Play()
    table.insert(effects, game.Players.LocalPlayer.folder.lastkilled.Value)
    if not looping then
      looping = true
      while #effects > 0 do
          east(table.remove(effects, 1))
      end
      script.Parent.Frame:TweenSize(UDim2.new({0.032, 0},{0.011, 0}), Enum.EasingDirection.InOut, Enum.EasingStyle.Quint, 0.175, true) --fade out now
      looping = false
    end
end)
1 Like

yep, that’s must work perfectly, I think

thankyou for the help!


1 Like

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