How do I stop a function from running while another function is?

So when you click on the button it tweens a Frame onto the screen and that frame has an X button to close it. The X button also runs a tween to move the frame off of the screen. But if you spam both buttons it will glitch out since both functions are running too many times. I could use a debounce but the problem is they are on two different scripts. Any way I can disable the function without disabling the ENTIRE script?

If you need my code, screenshots, or any other resources just ask me.

Thanks :smiley:

image

SCRIPT 1

local PlayerGUI = game.Players.LocalPlayer.PlayerGui
local Stroke = PlayerGUI.OpenEggs.Frame:WaitForChild("Stroke")
local Btn = PlayerGUI.OpenEggs.Frame:WaitForChild("CloseBtn")
local TL = PlayerGUI.OpenEggs.Frame:WaitForChild("CloseBtn"):WaitForChild("TextLabel")
local GUI = PlayerGUI:WaitForChild("OpenEggs")

local TS = game:GetService("TweenService")

local Frame = GUI:WaitForChild("Frame")
local EggDecals = GUI:WaitForChild("EggDecals")
local Egg1 = EggDecals:WaitForChild("Egg1")
local Egg2 = EggDecals:WaitForChild("Egg2")

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Stroke.MouseButton1Down:Connect(function()
	TS:Create(Btn, TweenInfo.new(.1, Enum.EasingStyle.Exponential), {Size = UDim2.fromScale(.08,.099), Position = UDim2.fromScale(.942,-.029)}):Play()
	TS:Create(TL, TweenInfo.new(.1, Enum.EasingStyle.Exponential), {Size = UDim2.fromScale(.159,.185), TextSize = 75, Position = UDim2.fromScale(.495,.5)}):Play()
	TS:Create(Stroke, TweenInfo.new(.1, Enum.EasingStyle.Exponential), {Size = UDim2.fromScale(.092,.115), Position = UDim2.fromScale(.936,-.037)}):Play()
	TS:Create(Egg1, TweenInfo.new(.35, Enum.EasingStyle.Exponential, Enum.EasingDirection.In), {Position = UDim2.fromScale(0.69, Egg1.Position.Y.Scale)}):Play()
	TS:Create(Egg2, TweenInfo.new(.35, Enum.EasingStyle.Exponential, Enum.EasingDirection.In), {Position = UDim2.fromScale(0.192, Egg2.Position.Y.Scale)}):Play()

	wait(.4)
	EggDecals.Visible = false
	TS:Create(Frame, TweenInfo.new(.4, Enum.EasingStyle.Exponential, Enum.EasingDirection.In), {Position = UDim2.fromScale(.5,2.493)}):Play()
end)

Stroke.MouseButton1Up:Connect(function() 
	TS:Create(Btn, TweenInfo.new(.1, Enum.EasingStyle.Exponential), {Size = UDim2.fromScale(0.102,0.125), Position = UDim2.fromScale(.932,-.045)}):Play()
	TS:Create(TL, TweenInfo.new(.1, Enum.EasingStyle.Exponential), {Size = UDim2.fromScale(0.159,0.185), TextSize = 100, Position = UDim2.fromScale(.495,.5)}):Play()
	TS:Create(Stroke, TweenInfo.new(.1, Enum.EasingStyle.Exponential), {Size = UDim2.fromScale(.115,.151), Position = UDim2.fromScale(.925,-.054)}):Play()
end)

Stroke.MouseEnter:Connect(function()
	TS:Create(Btn, TweenInfo.new(.1, Enum.EasingStyle.Exponential), {Size = UDim2.fromScale(0.113,0.14), Position = UDim2.fromScale(.926,-.054)}):Play()
	TS:Create(TL, TweenInfo.new(.1, Enum.EasingStyle.Exponential), {Size = UDim2.fromScale(0.159,0.185), TextSize = 100, Position = UDim2.fromScale(.495,.5)}):Play()
	TS:Create(Stroke, TweenInfo.new(.1, Enum.EasingStyle.Exponential), {Size = UDim2.fromScale(.126,.166), Position = UDim2.fromScale(.919,-.062)}):Play()
end)

Stroke.MouseLeave:Connect(function()
	TS:Create(Btn, TweenInfo.new(.1, Enum.EasingStyle.Exponential), {Size = UDim2.fromScale(0.102,0.125), Position = UDim2.fromScale(.932,-.045)}):Play()
	TS:Create(TL, TweenInfo.new(.1, Enum.EasingStyle.Exponential), {Size = UDim2.fromScale(0.159,0.185), TextSize = 100, Position = UDim2.fromScale(.495,.5)}):Play()
	TS:Create(Stroke, TweenInfo.new(.1, Enum.EasingStyle.Exponential), {Size = UDim2.fromScale(.115,.151), Position = UDim2.fromScale(.925,-.054)}):Play()
end)

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Btn.MouseButton1Down:Connect(function()
	TS:Create(Btn, TweenInfo.new(.1, Enum.EasingStyle.Exponential), {Size = UDim2.fromScale(.08,.099), Position = UDim2.fromScale(.942,-.029)}):Play()
	TS:Create(TL, TweenInfo.new(.1, Enum.EasingStyle.Exponential), {Size = UDim2.fromScale(.159,.185), TextSize = 75, Position = UDim2.fromScale(.495,.5)}):Play()
	TS:Create(Stroke, TweenInfo.new(.1, Enum.EasingStyle.Exponential), {Size = UDim2.fromScale(.092,.115), Position = UDim2.fromScale(.936,-.037)}):Play()
	TS:Create(Egg1, TweenInfo.new(.35, Enum.EasingStyle.Exponential, Enum.EasingDirection.In), {Position = UDim2.fromScale(0.69, Egg1.Position.Y.Scale)}):Play()
	TS:Create(Egg2, TweenInfo.new(.35, Enum.EasingStyle.Exponential, Enum.EasingDirection.In), {Position = UDim2.fromScale(0.192, Egg2.Position.Y.Scale)}):Play()

	wait(.4)
	EggDecals.Visible = false
	TS:Create(Frame, TweenInfo.new(.4, Enum.EasingStyle.Exponential, Enum.EasingDirection.In), {Position = UDim2.fromScale(.5,2.493)}):Play()
end)

Btn.MouseButton1Up:Connect(function() 
	TS:Create(Btn, TweenInfo.new(.1, Enum.EasingStyle.Exponential), {Size = UDim2.fromScale(0.102,0.125), Position = UDim2.fromScale(.932,-.045)}):Play()
	TS:Create(TL, TweenInfo.new(.1, Enum.EasingStyle.Exponential), {Size = UDim2.fromScale(0.159,0.185), TextSize = 100, Position = UDim2.fromScale(.495,.5)}):Play()
	TS:Create(Stroke, TweenInfo.new(.1, Enum.EasingStyle.Exponential), {Size = UDim2.fromScale(.115,.151), Position = UDim2.fromScale(.925,-.054)}):Play()
end)

Btn.MouseEnter:Connect(function()
	TS:Create(Btn, TweenInfo.new(.1, Enum.EasingStyle.Exponential), {Size = UDim2.fromScale(0.113,0.14), Position = UDim2.fromScale(.926,-.054)}):Play()
	TS:Create(TL, TweenInfo.new(.1, Enum.EasingStyle.Exponential), {Size = UDim2.fromScale(0.159,0.185), TextSize = 100, Position = UDim2.fromScale(.495,.5)}):Play()
	TS:Create(Stroke, TweenInfo.new(.1, Enum.EasingStyle.Exponential), {Size = UDim2.fromScale(.126,.166), Position = UDim2.fromScale(.919,-.062)}):Play()
end)


Btn.MouseLeave:Connect(function()
	TS:Create(Btn, TweenInfo.new(.1, Enum.EasingStyle.Exponential), {Size = UDim2.fromScale(0.102,0.125), Position = UDim2.fromScale(.932,-.045)}):Play()
	TS:Create(TL, TweenInfo.new(.1, Enum.EasingStyle.Exponential), {Size = UDim2.fromScale(0.159,0.185), TextSize = 100, Position = UDim2.fromScale(.495,.5)}):Play()
	TS:Create(Stroke, TweenInfo.new(.1, Enum.EasingStyle.Exponential), {Size = UDim2.fromScale(.115,.151), Position = UDim2.fromScale(.925,-.054)}):Play()
end)

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

SCRIPT 2


local Button = game.Players.LocalPlayer.PlayerGui:WaitForChild("Button")
local point = game.Workspace.MainFolder:WaitForChild("Eggs"):WaitForChild("Basic Egg")
local OpenEggs = game.Players.LocalPlayer.PlayerGui:WaitForChild("OpenEggs")
local Frame = game.Players.LocalPlayer.PlayerGui:WaitForChild("OpenEggs"):WaitForChild("Frame")

local EggDecals = game.Players.LocalPlayer.PlayerGui:WaitForChild("OpenEggs"):WaitForChild("EggDecals")
local Egg1 = EggDecals:WaitForChild("Egg1")
local Egg2 = EggDecals:WaitForChild("Egg2")

local tweenService = game:GetService("TweenService")
local RS = game:GetService("RunService")

local TextButton = Button.TextButton
local UIS = game:GetService("UserInputService")

local isPlayerHoldingDownE = false

local debounceToStopSpam_1 = false
local debounceToStopSpam_2 = false

RS.Heartbeat:Connect(function()
	local players = game.Players:GetPlayers()
	for index, player in pairs(players) do
		if player.Character then
			local target = player.Character
			local distance = (point.Position - target.HumanoidRootPart.Position).Magnitude 

			local radius = 5

			if distance < radius then
				
				Button.Enabled = true
				tweenService:Create(Button, TweenInfo.new(.3, Enum.EasingStyle.Exponential), {Size = UDim2.fromScale(4.5,4.5)}):Play()
				
			else
				tweenService:Create(Button, TweenInfo.new(.3, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out), {Size = UDim2.fromScale(.6,.6)}):Play()
				task.wait(.01)
				Button.Enabled = false
			end
		end
	end
end)

game.Players.LocalPlayer.PlayerGui.Button.TextButton.MouseButton1Click:Connect(function()
	OpenEggs.Enabled = true
	tweenService:Create(Frame, TweenInfo.new(.4, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out), {Position = UDim2.fromScale(.5,.493)}):Play()
	wait(.4)
	EggDecals.Visible = true
	tweenService:Create(Egg1, TweenInfo.new(.35, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out), {Position = UDim2.fromScale(0.805, Egg1.Position.Y.Scale)}):Play()
	tweenService:Create(Egg2, TweenInfo.new(.35, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out), {Position = UDim2.fromScale(0.043, Egg2.Position.Y.Scale)}):Play()
end)



-- ANIMATION AND CLICK ^^^^^^^^^



----------------------------------------------------------------------------------------------------------------------------------------------


-- PRESS E  VVVVVVVVVV


RS.Heartbeat:Connect(function()
	local players = game.Players:GetPlayers()
	for index, player in pairs(players) do
		if player.Character then
			local target = player.Character
			local distance = (point.Position - target.HumanoidRootPart.Position).Magnitude 
			local radius = 5
			if isPlayerHoldingDownE then
				if debounceToStopSpam_1 == false  then
					debounceToStopSpam_1 = true
					debounceToStopSpam_2 = false
					--print("player is holding down E!")
				end

				if distance < radius then
					OpenEggs.Enabled = true
					tweenService:Create(Frame, TweenInfo.new(.4, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out), {Position = UDim2.fromScale(.5,.493)}):Play()
					wait(.4)
					EggDecals.Visible = true
					tweenService:Create(Egg1, TweenInfo.new(.35, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out), {Position = UDim2.fromScale(0.805, Egg1.Position.Y.Scale)}):Play()
					tweenService:Create(Egg2, TweenInfo.new(.35, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out), {Position = UDim2.fromScale(0.043, Egg2.Position.Y.Scale)}):Play()
				else
				--	print("not close enough!")
				end
			else
				if debounceToStopSpam_2 == false then
					debounceToStopSpam_2 = true
					debounceToStopSpam_1 = false
					--print("player is NOT holding down E!")
				end
			end

		end
	end
end)

UIS.InputBegan:Connect(function(input)
	if input.KeyCode == Enum.KeyCode.E then
		isPlayerHoldingDownE = true
	end
end)

UIS.InputEnded:Connect(function(input)
	if input.KeyCode == Enum.KeyCode.E then
		isPlayerHoldingDownE = false
	end
end)

VIDEO

1 Like

Yeah you could provide us the script.

1 Like

it might be like… a lot… like its bad

Just show it anyways. We all need to improve somehow

1 Like

Ill put screenshots of hierarchy in sec

So for the tweens there is a thing called tween.Completed

I’m guessing you could add that.

But why don’t you just make it not visible? Maybe it wouldn’t look the best but you could try to do it.

Another way you could do this is a control variable lets say:

local IsGuiOpen = false

-- set IsGuiOpen to true when gui open

button.MouseButton1Down:Connect(function()
    if IsGuiOpen == false then 
    IsGuiOpen = true 
-- do the gui opening

    end
end)

Next time when you are going to click the button the IsGuiOpen variable will be set to true so it will do nothing. And upon opening it will be set to false again.

1 Like

It seems like all you need is a debounce that’s seen by both scripts.

I would recommend you to use :SetAttribute() to set a debounce. That way both scripts can watch for it.

You could do

GUI:SetAttribute("UIAnimating", true)

-- your two scripts:
if GUI:GetAttribute("UIAnimating") then
    return -- cancel the click event since the UI is already running
end
1 Like

Im kind of new to scripting, so your saying I create an attribute and if it’s true and the function runs then it will stop? Return means to stop right?

Thats also a debounce right? I guess that could work too.

Yep that also counts as a debounce.

1 Like

I have to go so ill be gone for a while, Ill check back on any other replies. Thanks for helping.

1 Like

Yeah, use :SetAttribute() to write a value to an object, all scripts can access the object and read the value with :GetAttribute(), you can use this to have multiple scripts communicate.

You can code it like that if you want. Usually if debounces are true you call return. You don’t continue your code.

Return means to not continue the rest of the code for your case.

I would recommend you make a separate game, give this a read, and copy and paste its code to understand debouncing.

2 Likes

Will do.


Hey, is there a better way to write all the animations? Because it’s just a long list of tweens… is there any way to short it down and make it more efficient and not all messy?

Any style of a “debounce”, or flag would work. It donsen’t look like you use them… yet.
Some things you may be doing could even be use for a flag. Like check if a window is open, exc.

2 Likes

You can just Directly Tween The Object by using

Frame:TweenPosition()

It has as an option where you can allow it to override an in-progress tween, it is better to use that method instead of a debounce for a Gui Tween

2 Likes

I think what you have is good enough even though it’s not perfect. You should focus on getting the rest of your game working.

If I were to do a UI animation system like that I would store the numbers in a table instead and use a state machine.

With your code right now, what you can do to improve it slightly is to not do TS:Create() every time you want to run the tween. Just create it at the start and reuse it, or you can use a function to generate the tweens.

local function CreateBtnTween(sizeX, sizeY, posX, posY)
    return TS:Create(Btn, TweenInfo.new(.1, Enum.EasingStyle.Exponential), {Size = UDim2.fromScale(sizeX, sizeY), Position = UDim2.fromScale(posX, posY)}):Play()
end

local myBtn = CreateBtnTween(0.08, 0.099, 0.942, -0.029)

Stroke.MouseButton1Down:Connect(function()
	myBtn:Play() -- you can reuse this instead of having to :Create it every time
	...

Hopefully it’s not too confusing. I think what you have is good enough. If you need more information maybe look up at other UI tutorials for tips.

2 Likes

So your saying if I press X while it’s opening there should be no problem of bugging because it stops the other tween from running while it runs?

1 Like

Ok I get what you mean the only thing is that most of my tweens have different numbers so I would also have to make a lot of variables for my tweens right? But it will still clean it up a bit correct?

Yes, if you are trying to tween the object that is currently being Tweened, then the object will not run the other Tween that removes the Frame from the screen. Only if override is false

1 Like