GUI doesn't update as I intend

So I have cooldown indicators in my game, and they work, but they stack sometimes. For some unknown reason, Only updates the position when the frame gets created. Doesn’t work after. I have a feeling I’ve overlooked something, but I’m unsure.

cooldowns = {}


game.ReplicatedStorage.Remotes.CreateCooldown.OnClientEvent:Connect(function(ReloadTime, AttackType, AbilityName)
	
	task.spawn(function()
		local myTweenInfo = TweenInfo.new(ReloadTime, Enum.EasingStyle.Linear)
		local gui = script.CooldownFrame:Clone()
		gui.Parent = script.Parent
		gui.AbilityName.Text = AbilityName
		gui.Container.TextLabel.Text = AttackType
		local z=table.insert(cooldowns,gui)
		for i=1, #cooldowns do
				print(i)
				cooldowns[i].Position = UDim2.new(0.699,0,-0 + i / 10,0)
		end
		local myTween = game:GetService("TweenService"):Create(gui:FindFirstChild("Progress", true), myTweenInfo, {Size = UDim2.new(1, 0, 1, 0)})
		myTween:Play()
		task.wait(ReloadTime)
		table.remove(cooldowns,z)
		for i=1, #cooldowns do
			if cooldowns[i] ~= gui then
			print(i)
				cooldowns[i].Position = UDim2.new(0.699,0,-0 + i / 10,0)
				
		   end
		end
		gui:Destroy()
	end)
end)

This is unnecessary remote event connection are already a separate thread.

They still stack. I want my GUI frames that are in existance to update when the table gets updated.

They don’t stack, they only stack when OnClientEvent or OnServerEvent still not connected.

You need to store this as a variable.

What do you mean? Update a frame that does not exist is not possible it’s because you already have destroyed it:

Ok, so when a cooldown ends, every other cooldown gets moved 1 up, and when a new one is made, the opposite happens.

Have you tried printing the cooldowns[i].Parent? If it’s a nil of course it’s not gonna update it’s position.

Edit: Is this even necessary: if cooldowns[i] ~= gui then didn’t you already remove it from the table?

Alright, I’ll print the parent real quick to see what it returns.

Alright, so when a cooldown gets destroyed it returns nil, however I believe that’s the cooldown GETTING removed, hold on, I’ll make it ignore the one getting deleted.

Alright, I got it to kind of work, but it sometimes leaves empty spaces now.

You probably got the math wrong shouldn’t this be the size of the Frame, not some random number:

local Size = gui.AbsoluteSize
local ParentSize = gui.Parent.AbsoluteSize -- if it's parent is not a ScreenGui

 -- else we need to get the size of the screen
 -- if the parent is a ScreenGui
local function GetScreenSize(): Vector2
    local ScreenGui= Instance.new("ScreenGui", PlayerGui)
    local Frame = Instance.new("Frame", ScreenGui)
    Frame.Size = UDim2.new(1, 0, 1, 0)

    local ScreenSize = Frame.AbsoulteSize
    ScreenGui:Destroy()

    return ScreenSize
end

local UnitSize = if gui.Parent:IsA("ScreenGui") then Size / GetScreenSize() else (Size / ParentSize)

UDim2.new(0.699, 0, UnitSize * i,0)

It works fine with the sizing, but it skips out that space for the cooldowns, will send clip of what i mean in a bit