Need help with how to get my function ended

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? I want my function to end when i press the Close button

  2. What is the issue? After i press the close button my gui closes but when i open it again the old function still listens to the ChildRemoved and ChildAdded events causing a nil value error. So i want the ChildRemoved and ChildAdded not to run at all.

  3. What solutions have you tried so far? I have tried looking here but found nothing that helped. I have also tried returning the function but that didnt do anything.

Here is my script:

local container = script.Parent

game.ReplicatedStorage.Events.ContainerEvent.OnServerEvent:Connect(function(player)

	-- Generate gui for container function

	local function GenerateContainerGui(containerGuiContainer, Item)
		-- If itembutton already exists
		if containerGuiContainer:FindFirstChild(Item.Name) then
			local ItemButton =  containerGuiContainer:FindFirstChild(Item.Name)
			local amount = 0
			for i, child in ipairs(container.Inventory:GetChildren()) do
				if child.Name == Item.Name then
					amount += 1
				end
			end
			ItemButton:WaitForChild("Amount").Text = amount
			if amount <= 0 then
				ItemButton:Destroy()
			end
			-- If itembutton doesnt exist
		else
			local ItemButton = containerGuiContainer:WaitForChild("ItemFrame"):Clone()
			ItemButton.Name = Item.Name
			ItemButton.Parent = containerGuiContainer
			ItemButton.Amount.Text = "1"
			ItemButton.Visible = true

			ItemButton.MouseButton1Click:Connect(function()
				local ItemToTransfer = container.Inventory:FindFirstChild(Item.Name)
				print(container, ItemToTransfer)
				if ItemToTransfer then
					print(ItemButton.Parent.Name)
					TransferItem(ItemToTransfer, player.Inventory)
				end
			end)
		end
	end

	local function UpdateContainerGui(containerGuiContainer, Item)
		if Item then
			GenerateContainerGui(containerGuiContainer, Item)
		else
			for i, Item in pairs(container.Inventory:GetChildren()) do
				GenerateContainerGui(containerGuiContainer, Item)
			end
		end
	end

	-- Generate gui for inventory function

	local function GenerateInventoryGui(containerGuiInventory, Item)
		-- If itembutton already exists
		if containerGuiInventory:FindFirstChild(Item.Name) then
			local ItemButton = containerGuiInventory:FindFirstChild(Item.Name)
			local amount = 0
			for i, child in ipairs(player.Inventory:GetChildren()) do
				if child.Name == Item.Name then
					amount += 1
				end
			end
			ItemButton:WaitForChild("Amount").Text = amount
			if amount <= 0 then
				ItemButton:Destroy()
			end
			-- If itembutton doesnt exist
		else
			local ItemButton = containerGuiInventory:WaitForChild("ItemFrame"):Clone()
			ItemButton.Name = Item.Name
			ItemButton.Parent = containerGuiInventory
			ItemButton.Amount.Text = "1"
			ItemButton.Visible = true

			ItemButton.MouseButton1Click:Connect(function()
				local ItemToTransfer = player.Inventory:FindFirstChild(Item.Name)
				print(container, ItemToTransfer)
				if ItemToTransfer then
					print(ItemButton.Parent.Name)
					TransferItem(ItemToTransfer, container.Inventory)
				end
			end)
		end
	end

	local function UpdateInventoryGui(containerGuiInventory, Item)
		if Item then
			GenerateInventoryGui(containerGuiInventory, Item)
		else
			for i, Item in pairs(player.Inventory:GetChildren()) do
				GenerateInventoryGui(containerGuiInventory, Item)
			end
		end
	end

	script.Parent.open:Play()
	local containerGui = game.ReplicatedStorage.Guis.Container:Clone()
	containerGui.Parent = player.PlayerGui.MainGui
	containerGui.Visible = true
	containerGui.Bars.ContainerName.Text = container.Name
	containerGui.ContainerSpace.Text = (#container.Inventory:GetChildren() .. " / " .. container.InventorySize.Value)
	containerGui.InventorySpace.Text = (#player.Inventory:GetChildren() + #player.Hotbar:GetChildren() .. " / " .. player.InventorySize.Value)

	UpdateContainerGui(containerGui.Container)
	UpdateInventoryGui(containerGui.Inventory)

	local function ChildChanged(Item)
		if containerGui:FindFirstChild("ContainerSpace") then
			containerGui.ContainerSpace.Text = (#container.Inventory:GetChildren() .. " / " .. container.InventorySize.Value)
			containerGui.InventorySpace.Text = (#player.Inventory:GetChildren() + #player.Hotbar:GetChildren() .. " / " .. player.InventorySize.Value)
		end
		if Item then
			print(containerGui.Container.Parent)
			UpdateContainerGui(containerGui.Container, Item)
			UpdateInventoryGui(containerGui.Inventory, Item)
		end
	end

	containerGui.Bars.Close.MouseButton1Down:Connect(function() -- I want this to end the entire OnServerEvent function
		containerGui:Destroy()
		game.ReplicatedStorage.Events.PlayClientSound:FireClient(player, "Click")
		return
	end)

	container.Inventory.ChildAdded:Connect(ChildChanged)
	container.Inventory.ChildRemoved:Connect(ChildChanged)
end)

function TransferItem(Item, TargetParent)
	Item.Parent = TargetParent
	if TargetParent.Parent == container then
		Item.PrimaryPart.Anchored = true
		Item:MoveTo(Vector3.new(0,10,0))
	end
end

You can try storing the event connections in a variable, and then disconnecting them afterwards.
Something like this:

local childAdded = container.Inventory.ChildAdded:Connect(ChildChanged)
local childRemoved = container.Inventory.ChildRemoved:Connect(ChildChanged)

And in the close function you need to have this:

childAdded:Disconnect()
childRemoved:Disconnect()

Thanks for answering, This worked perfectly.

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