How to cancel a reload function on tool unequip

I want to cancel this reload function on unequip

it not working aaaaa

I have tried to return end on unequip but it dont work

reload function

script.Parent.Reload.OnServerEvent:Connect(function()
	if not equipped or reloading then return end

	reloading = true
	script.Parent.Handle.Reloadsound:Play()
	task.wait(reloadtime)
	Mag.Value = 7
	reloading = false
end)

Where you getting the equipped?

equip code

script.Parent.Equipped:Connect(function()
	equipped = true
	params.FilterDescendantsInstances = {script.Parent.Parent}
end)

script.Parent.Unequipped:Connect(function()
	equipped = false
end)

I am not sure if this will work I am going off pure memory but try this:

local connection = nil

local function Reload()
	reloading = true
	script.Parent.Handle.Reloadsound:Play()
	task.wait(reloadtime)
	Mag.Value = 7
	reloading = false
end

script.Parent.Reload.OnServerEvent:Connect(function()
    connection = Reload()
end)
script.Parent.Unequipped:Connect(function()
	if connection ~= nil then
        connection:Disconnect()
    end
end)

didnt work, i have done it before but i deleted the tool that had the code. it used some variable in the function and some hacky method to cancel the function

You can use a boolean to detect if you can reload or not (wait you tried that already)

Have you looked into the task and the coroutine libraries? Both of these libraries have a function that you can use to cancel()/close() threads, respectively. I recommend looking at the documentations for these libraries for future reference and receiving better understanding and knowledge of their uses.

In this example, I’ll be using the coroutine library so that we can also check the status of the thread (using coroutine.status()) in your reload() function. If the returned value is not "dead", the thread is running. Yes, coroutine.status() can return other states that suggest the thread is not "dead", but not "running" either. However, in this case, it will only matter if the thread is "dead" or not.

(The example snippet:)

local tool = script.Parent

local reloadEvent = tool.Reload

local equipped = false
local reloading: thread = nil

local function isRunning(co: thread): boolean
    return if coroutine.status(co) ~= "dead" then true else false
end

local function reload(): ()
    -- ...
end

reloadEvent.OnServerEvent:Connect(function()
    if not equipped or reloading and isRunning(reloading) then
        return
    end

    reloading = coroutine.create(reload)
    coroutine.resume(reloading)
end)

tool.Unequipped:Connect(function()
    equipped = false
    if reloading then
        coroutine.close(reloading)
    end
end)

alright ill try this ghhhhhhhhhhhhhhhhhh 30 letters

aight it works but it wont reload again do i have to resume/create a new coroutine or something?

May I see your reload() function and the function connected to the Tool.Equipped event?

And no, you shouldn’t have to create() a new coroutine nor resume() one since that’s already being done in the function connected to the Reload.OnServerEvent event.

Edit: I re-read the documentations and did more research. You cannot close() a coroutine when it’s running – it has to be in a close()able state, like "suspended". Even though you said that it does stop the reloading action, maybe this is the cause of your issue.

If so, my bad. We can try using the task library. I’ll be playing off of an older post that worked:

local tool = script.Parent

local reloadEvent = tool.Reload

local equipped = false
local reloading: thread = nil

local function reload(): ()
    -- ...
    reloading = nil
end

reloadEvent.OnServerEvent:Connect(function()
    if not equipped or reloading then
        return
    end

    reloading = task.spawn(reload)
end)

tool.Unequipped:Connect(function()
    equipped = false

    if reloading then
        task.cancel(reloading)
        reloading = nil
    end
end

I saw that someone else posted, too, but I just wanted to fix my possible mistake, in case the revision could ever help you in the future.

A much easier way to do this would be to update the Reload function:

local function Reload()
	reloading = true
	script.Parent.Handle.Reloadsound:Play()
	local end_t = tick() + reload_time -- The time at which reload will end
	while tick() <= end_t do 
		if not equipped then
			return -- If equipped is false the function will return
		end
		task.wait()
	end
	-- This only runs if the function didn't return during the loop
	Mag.Value = 7
	reloading = false
end

With this you don’t need to update any other code and it should work good

1 Like

Hello. Ive done this a while ago. This is how I did it.

-- Hello. Here is something that MAY help you.
local equipped = false
local reloading = false
local reloadtime = 2 -- change this
local Mag = 30 -- change this

function equip_()
	equipped = true
end

function unequip_()
	equipped = false
	
	script.Parent.Handle.Reloadsound:Stop()
end

local connection

function reload_()
	if not equipped or reloading then return end
	
	reloading = true
	script.Parent.Handle.Reloadsound:Play()

	coroutine.wrap(function()
		while reloading == true do
			task.wait()

			if equipped == false then
				return
			end
		end
	end)()

	task.wait(reloadtime)
	Mag.Value = 7
	reloading = false
end

However, the post above me made bye mayoozzzz would also work, so feel free to mark his post too as solution.

1 Like

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