I’m experimenting on ways to disconnect from a module script, and right now this method isn’t working:
Module Script:
function clientCombat.lmb(atkType, connection)
if not connection then return end
--Rest of code
Local Script:
local clientCombat = require(game.StarterPlayer.StarterCharacterScripts.ClientCombat)
local atkType = game.ReplicatedStorage.Combat.Fists.Punch
local Fists = script.Parent
local connection
Fists.Equipped:Connect(function()
connection = true
print(connection) --This helps me check the value of 'connection,' and the output shows that it's working properly
clientCombat.lmb(atkType, connection)
end)
Fists.Unequipped:Connect(function()
connection = false
print(connection)
end)
After I unequip the tool, the module script is still ongoing. Is there any way to fix this, or is there an alternative solution?
I don’t really understand what you’re trying to do here. You’re passing a boolean to clientCombat, so the value it receives is going to be the value it references, regardless of whether or not connection inside of your local script is updated.
I’m trying to disconnect from a module script, and as for why I have the connection variable in both the local and the module script, it is because the variable updates the corresponding one in the module script when it is inside the parentheses. Although I’m not sure if it can update it twice.
I’m still not too sure what you mean sorry. Typically when working with Roblox event listeners ‘disconnect’ means to kill an event listener. Is that what you’re trying to do?
When you pass a variable to a function it doesn’t update if the caller changes the value of the variable since it’s a reference to the value itself, not to the variable if that makes sense.
local a = true
local function f(var)
task.delay(1, print, var) --> true
end
f(a)
a = false
Well sure, this is only the client side of it that controls the cooldowns and etc
function clientCombat.lmb(atkType, connection)
if not connection then return end
local rs = game.ReplicatedStorage
local gds = rs.Combat.GlobalDelay.Start
local gde = rs.Combat.GlobalDelay.End
local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local debounce = false
gds.OnClientEvent:Connect(function()
debounce = true
end)
gde.OnClientEvent:Connect(function()
debounce = false
end)
mouse.Button1Down:Connect(function()
if debounce then return end
atkType:FireServer()
end)
end
Ok yeah you aren’t returning any connections back to the local script so there won’t be any connections to disconnect.
I’m not too sure which connection(s) are relevant, but you could just return a table of connections.
function clientCombat.lmb(atkType, connection)
-- ...
local connections = {}
-- ...
local debounce = false
table.insert(connections, gds.OnClientEvent:Connect(function()
debounce = true
end))
table.insert(connections, gde.OnClientEvent:Connect(function()
debounce = false
end))
table.insert(connections, mouse.Button1Down:Connect(function()
if debounce then return end
atkType:FireServer()
end))
return connections -- returns the table of connections back to the local script that called this function
Then on your client script,
local connections = clientCombat.lmb(atkType, connection) -- now a table of connection objects (which is the we returned earlier)
-- to disconnect/cleanup all the connections,
for _, connection in connections do
connection:Disconnect()
end
Here’s my current local script (the module script is changed to the one you created), I’m not sure if it’s implemented correctly, or what the connection should be defined as:
local clientCombat = require(game.StarterPlayer.StarterCharacterScripts.ClientCombat)
local atkType = game.ReplicatedStorage.Combat.Fists.Punch
local Fists = script.Parent
local connections = clientCombat.lmb(atkType, connection)
Fists.Equipped:Connect(function()
clientCombat.lmb(atkType, connection)
end)
Fists.Unequipped:Connect(function()
for _, connection in connections do
connection:Disconnect()
end
end)
Sorry for late response, was responding to someone else.
You’d just make a variable that’s accessible in the scope of of both your cleanup function and your equipped connection
-- ...
local connections
local function cleanup()
if not connections then
return
end
for _, connection in connections do
connection:Disconnect()
end
end
fists.Equipped:Connect(function()
cleanup() -- probably not necessary but in case fists.Equipped is fired twice for what ever reason
connections = clientCombat.lmb(atkType, connection)
end)
fists.Unequipped:Connect(cleanup) -- clean up connections when tool's unequipped
Yes you would have to fill in for the missing variables (which is what the ellipses represent). They’d just be the same as the boolean from your original post
It could also just be hardcoded as true or you could just remove the param entirely because I don’t think changing its value would change any behaviour but I could be overlooking it
Sorry for the really late reply, I had issues with my keyboard the other day, then issues with being unable to load into my place right after. Other stuff came along the way, but fortunately I’m back and I have finally been able to find a solution very similar to yours:
local clientCombat = {}
local eventConn = {}
function clientCombat.lmb(atkType)
local rs = game.ReplicatedStorage
local gds = rs.Combat.GlobalDelay.Start
local gde = rs.Combat.GlobalDelay.End
local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local debounce = false
local gdsConn = gds.OnClientEvent:Connect(function()
debounce = true
end)
local gdeConn = gde.OnClientEvent:Connect(function()
debounce = false
end)
local mouseConn = mouse.Button1Down:Connect(function()
if debounce then return end
atkType:FireServer()
end)
table.insert(eventConn, gdsConn)
table.insert(eventConn, gdeConn)
table.insert(eventConn, mouseConn)
end
function clientCombat.Disconnect()
for _, connection in ipairs(eventConn) do
connection:Disconnect()
end
eventConn = {}
end
return clientCombat
In my module script, I created a table called EventConn (EventConnections) to store parts of the function in which I am able to disconnect from later. Inside the main function, I inserted the smaller functions that control the events of gds, gde, and mouse into the table. Then I added another primary function called Disconnect that disconnects the events from EventConn when called.
local clientCombat = require(game.StarterPlayer.StarterCharacterScripts.Combat.ClientCombat)
local atkType = game.ReplicatedStorage.Combat.Fists.Punch
local Fists = script.Parent
Fists.Equipped:Connect(function()
clientCombat.lmb(atkType)
end)
Fists.Unequipped:Connect(function()
clientCombat.Disconnect()
end)
For my local script, not much has changed, and I only altered what was in the Unequipped function; when Fists are unequipped, the function calls the Disconnect function from the module script.