How would you stop a function from the outside?

So I am trying to make a lever with a powerup animation next to it. The only problem is that I cannot stop the power-up animation when the player lets go of the lever. It just continues. Is there any way to stop a function while it’s running? I have tried using coroutines to no avail. I need to stop the Holding() function while it’s running.

Here is the code I am working with:

local TweenService = game:GetService("TweenService")

local switchon = script.Parent.Parent.Parent.switchon
local switchoff = script.Parent.Parent.Parent.switchoff
local switch = script.Parent.Parent.Parent.switch
local StatusLCD = script.Parent.Parent.Parent.StatusLCD

local PowerOn = true
local PoweringOn = false

local PowerController = require(game.ServerScriptService.PowerController)

local PowerLvl1 = StatusLCD.PowerLevel1
local PowerLvl2 = StatusLCD.PowerLevel2
local PowerLvl3 = StatusLCD.PowerLevel3
local PowerLvl4 = StatusLCD.PowerLevel4
local PowerLvl5 = StatusLCD.PowerLevel5

script.Parent.Triggered:Connect(function(Player)
	if PowerController:RequestPower() ~= 0 and PoweringOn == true and PowerOn == true then
		Player:Kick("\n\nSuspicious Client Behaviour\n\n")
	elseif PowerController:RequestPower() == 0 and PoweringOn == false and PowerOn == false then
		PowerController:ReactivatePower()
		script.Parent.Enabled = false
		PowerOn = true
	end
end)

function Holding()
	PoweringOn = true
	if PoweringOn then
		local turnontween = TweenService:Create(switch, TweenInfo.new(30, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut), {CFrame = switchon.CFrame}):Play()
		script.Parent.Parent.Parent.StatusLCD.UpdateLCD.Disabled = true
		PowerLvl1.Transparency = 0
		PowerLvl2.Transparency = 1
		PowerLvl3.Transparency = 1
		PowerLvl4.Transparency = 1
		PowerLvl5.Transparency = 1
	end
	task.wait(6)
	if PoweringOn then PowerLvl2.Transparency = 0 end
	task.wait(6)
	if PoweringOn then PowerLvl3.Transparency = 0 end
	task.wait(6)
	if PoweringOn then PowerLvl4.Transparency = 0 end
	task.wait(6)
	if PoweringOn then PowerLvl5.Transparency = 0 end
	task.wait(6)
	PoweringOn = false
end

script.Parent.PromptButtonHoldBegan:Connect(Holding)

script.Parent.PromptButtonHoldEnded:Connect(function(Player)
	if PoweringOn == true then
		local turnofftween = TweenService:Create(switch, TweenInfo.new(.35, Enum.EasingStyle.Quart, Enum.EasingDirection.In), {CFrame = switchoff.CFrame}):Play()
		script.Parent.Parent.Parent.StatusLCD.UpdateLCD.Disabled = false
		print("Hey")	
	end
end)

function Update()
	while task.wait(0.5) do
		if PowerController:RequestPower() == 0 and PowerOn == true then
			PowerOn = false
			local turnofftween = TweenService:Create(switch, TweenInfo.new(.35, Enum.EasingStyle.Quart, Enum.EasingDirection.In), {CFrame = switchoff.CFrame}):Play()
			task.wait(1)
			script.Parent.Enabled = true
		end	
	end
end

task.spawn(Update)

This code is still sloppy as I always clean up my code at the end. I would be thankful for an answer.

You are waiting a long period of time, which I don’t know how to break, BUT, if instead of a single wait, you call another function with a while loop and a debounce, you could break out of it immediately.

1 Like

The way your Holding function is written it is always going to do all the waits. If you moved all the waits inside the preceeding if block then the wait would only happen if PoweringOn is still true. Then in your handler for the PromptButtonHoldEnded event set PoweringOn to false, that would effectively stop Holding once the current wait expires.

not very efficient is it because that’s just excess?

If the goal is to be able to break a function from outside the function, you need access. A single debounce feels like the most efficient way to do that. Checking the debounce instead of waiting and doing nothing will not cost anything.

what? how will a while loop break the function? it’ll just yield it.

just make a bool value then used the :changed event to instantly receive a response that PoweringOn has changed values. (better than using loops, plus it doesn’t yield)