Issues with disconnecting from a module script

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.

1 Like

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.

1 Like

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
1 Like

I’m still new to scripting, and I’m a bit confused about your code. I have tried using ‘disconnect’ for the module script by doing

local connection
connection = clientCombat.lmb(atkType, connection)
connection:Disconnect()

but when I printed the connection, it returned a value of ‘nil.’

And here’s an example of what I meant earlier. This is the server script:

local leftAnim = "rbxassetid://13714125921"
require(game.ServerScriptService.Combat.CombatManager).basicAtk(leftAnim)

and this is the module script:

function combat.basicAtk(leftAnim)
anim.AnimationId = leftAnim

The module script knows that the value of ‘leftAnim’ is the one from the server script.

1 Like

I see, can you show the full lmb function? If you aren’t returning a connection, your variable connection will be nil.

1 Like

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
1 Like

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
1 Like

I have tested it, and for the client script, the connection value inside the parentheses isn’t defined yet.

1 Like

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)
2 Likes

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
1 Like

Again, the ‘connection’ variable (not the ‘connections’) isn’t defined.

1 Like

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

1 Like

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.

This did take a lot of attempts from ChatGPT.

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