So for an inventory I'm creating I need it to update the hot bar you know, to do that I'm using a changed event. The problemo is that if you keep using it it'll start to lag because the events keep stacking up. I need to know how to disconnect events.
(Not the entire script, just parts I think you'll need for context)
01 | function update() |
02 | print ( "Prime update" ) |
03 | if script.Parent.Image = = "" then |
04 | script.Parent.Amount.Visible = false |
05 | else |
06 | if player.Inventory:FindFirstChild(script.Parent.Item.Value)~ = nil and player.Inventory [ script.Parent.Item.Value ] .Value = = 0 then |
07 | script.Parent.Amount.Visible = false |
08 | script.Parent.Image = "" |
09 | script.Parent.Item.Value = "" |
10 | elseif player.Inventory:FindFirstChild(script.Parent.Item.Value)~ = nil then |
11 | script.Parent.Amount.Visible = true |
12 | script.Parent.Amount.Text = "x" ..player.Inventory [ script.Parent.Item.Value ] .Value |
13 | if a~ = nil then |
14 | a = nil |
15 | end |
16 | local a = player.Inventory [ script.Parent.Item.Value ] .Changed:connect(update) |
17 | end |
18 | end |
19 | end |
[Completed fixed version]
01 | local player = script.Parent.Parent.Parent.Parent.Parent.Parent.Parent |
02 | local a = nil |
03 | function onClicked() |
04 | if script.Parent.Image~ = "" then |
05 | if game.Workspace:WaitForChild(player.Name):FindFirstChild(script.Parent.Item.Value)~ = nil then |
06 | game.Workspace:WaitForChild(player.Name).Humanoid:UnequipTools() |
07 | else |
08 | game.Workspace:WaitForChild(player.Name).Humanoid:UnequipTools() |
09 | game.Workspace:WaitForChild(player.Name).Humanoid:EquipTool(game.ReplicatedStorage.assets.Items [ script.Parent.Item.Value ] :Clone()) |
10 | end |
11 | local kids = player.Backpack:GetChildren() |
12 | for i = 1 ,#kids do |
13 | if kids [ i ] .ClassName = = "Tool" then |
14 | kids [ i ] :Destroy() |
15 | end |
If you're ever in a situation where you're connecting multiple events to the same object within a loop, another event, or multiple times without disconnecting them, you need to fix that immediately. When setting up an event listener, ROBLOX does not overwrite the previous one (as you've probably figured out).
Instead, you need to disconnect the previous event manually if you're going to be throwing it away, or connecting more of the same events to the object. You can do this by using the disconnect method on what your connect
method returns. Here's an example:
1 | -- "PartTouched" now represents what "connect()" returns, which is the event signal for this individual event. |
2 | local PartTouched = Part.Touched:connect( function () |
3 | print ( "Part touched" ) |
4 | end ) |
5 |
6 | -- Once you have a reference to that signal, you can then disconnect it by calling the "disconnect()" method on it whenever you want. |
7 | PartTouched:disconnect() |
Now, sometimes you only want an event to fire once at a time. You could use a debounce strategy, which is probably better 90% of the time. But for that specific situation where the event must be disconnected right after it fires, this is how it'd be done:
A reference to the event must be defined outside it's callback function
Disconnect the event as soon as it fires
Understanding this, here's an example of how it'd be done:
01 | -- Making the local variable "PartTouched" with a default value of nil. Now we can reference this variable outside our callback function we pass to the event |
02 | local PartTouched |
03 |
04 | PartTouched = Part.Touched:connect( function () |
05 | -- We can disconnect it, since we set it to the signal the event returns |
06 | PartTouched:disconnect() |
07 |
08 | -- The rest of your code |
09 | print ( "Hello" ) |
10 | end ) |
While disconnecting events is important if you're going to be using creating more than one for the same object, it can also be unnecessary in avoidable situations. Most of the time, you can just have one event constantly listening for something without needing to mess with disconnect or debounce. In the case of your code, this can be implemented by simply taking your event connection out of your update function, and have it somewhere where it's only going to be created that one time.
Hope that helped, if you have any questions or if anything was unclear, just let me know and I'll get back to you as soon as possible.
Just put something like this in:
1 | myFunction:disconnect() |
Substitute 'myFunction' for the name of the function you want to disconnect.