System that only allows one menu in a table to be active at once?

Works Perfectly!
robloxapp-20240429-1655535.wmv (637.8 KB)

The only other thing I’d note is that it takes a bit for the new menu to open? Is there anyway the new menu can come up while the old one leaves? Maybe using delay()?

1 Like

Oh yeah, that’s because the closeGUI function is called first in that scenario, and it yields because of the tween.Completed:Wait(), making it wait until that’s completed before going back and calling openGUI on the new menu.

One way to make both Tweens run simultaneously in that scenario would be to call task.spawn() on the closeGUI function. An analogy for how that works could be if the two functions were in a checkout line at the store; instead of making openGUI wait for closeGUI to finish scanning every item and paying for it, closeGUI moves to a different checkout line so both can complete their tasks at the same time.


So the only thing that would change is in the updateCurrentMenu function of the ModuleScript when the if desiredFrameVisible == true and if activeMenuCheck ~= nil conditions are met.

-- Before
closeGUI(activeMenuCheck)

-- After
task.spawn(closeGUI, activeMenuCheck)

And just to make it easier to know what that entire function looks like after making that change, here it is:

function MenuModule.updateCurrentMenu(Frame, desiredFrameVisibility, tweenInfo)
	print(MenuModule.activeMenu)
	if Frame ~= nil then
		if desiredFrameVisibility == true then

			local activeMenuCheck = MenuModule.activeMenu
			if activeMenuCheck ~= nil then
				task.spawn(closeGUI, activeMenuCheck) -- Updated
			end
			
			MenuModule.activeMenu = Frame
			openGUI(Frame, tweenInfo)

		elseif desiredFrameVisibility == false then
            if Frame == MenuModule.activeMenu then
                MenuModule.activeMenu = nil
            end

			closeGUI(Frame, tweenInfo)
		end

	end
end

If you’d like to, you could post the full completed ModuleScript and LocalScript code here after making that change so that anyone else who ends up reading this thread will know what the “final” solution for the original question is, since it has now changed a decent amount since I wrote the post that you marked as a solution.

1 Like

Thanks, nice analogy.

I’ll post the final script tomorrow.

1 Like

Here is the Final Script as of now.

Please feel free to use this code!

MODULE SCRIPT

local MenuModule = {}

MenuModule.activeMenu = nil
MenuModule.defaultTweenInfo = TweenInfo.new(
	0.5, -- Time
	Enum.EasingStyle.Quad, -- Easing style
	Enum.EasingDirection.Out, -- Easing direction
	0, -- Repeat count (0 = no repeat)
	false, -- Reverses (true = reverse)
	0 -- Delay time   
)
local TweenService = game:GetService("TweenService")

local function openGUI(Frame, tweenInfo) -- Function based on what was included in the original post
	if not tweenInfo then
		tweenInfo = MenuModule.defaultTweenInfo
	end
	local targetPosition = UDim2.new(0.5, 0, 0.5, 0) -- Center of the screen
	local tween = TweenService:Create(Frame, tweenInfo, {Position = targetPosition})
	
	Frame.Visible = true
	tween:Play()
	
end

local function closeGUI(Frame, tweenInfo) -- Function based on what was included in the original post
	if not tweenInfo then
		tweenInfo = MenuModule.defaultTweenInfo
	end
	
	local targetPosition = UDim2.new(0.5, 0, 1.5, 0) -- Below the screen 
	local tween = TweenService:Create(Frame, tweenInfo, {Position = targetPosition})
	
	tween:Play()
	tween.Completed:Wait()
	
	Frame.Visible = false
	
end

function MenuModule.updateCurrentMenu(Frame, desiredFrameVisibility, tweenInfo)
	print(MenuModule.activeMenu)
	if Frame ~= nil then
		if desiredFrameVisibility == true then

			local activeMenuCheck = MenuModule.activeMenu
			if activeMenuCheck ~= nil then
				task.spawn(closeGUI, activeMenuCheck)
			end
			
			MenuModule.activeMenu = Frame
			openGUI(Frame, tweenInfo)

		elseif desiredFrameVisibility == false then
            if Frame == MenuModule.activeMenu then
                MenuModule.activeMenu = nil
            end

			closeGUI(Frame, tweenInfo)
		end

	end
end
return MenuModule

LOCAL SCRIPT

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local MenuModule = require(ReplicatedStorage.Modules.MenuModule)
print(MenuModule)

local Frame = script.Parent
local associatedButtonName = Frame.Name

local ImageButton = Frame.Parent.Parent:WaitForChild("Bottom Container"):WaitForChild("Toolbar"):WaitForChild(associatedButtonName)
local closeButton = Frame:WaitForChild("Close")

local function getTweenInfo()
	    return TweenInfo.new(
        0.5, -- Time
        Enum.EasingStyle.Quad, -- Easing style
        Enum.EasingDirection.InOut, -- Easing direction
        0, -- Repeat count (0 = no repeat)
        false, -- Reverses (true = reverse)
        0 -- Delay time
    )
--[[ If this needs to be specific for each menu, then you can retrieve it
in the same way you are already, but then have it sent to the ModuleScript.
Otherwise, a universal TweenInfo could be stored in the ModuleScript so these
LocalScripts don't have to communicate it every time a menu needs to be
opened or closed --]]

	-- If the function below calls this function, have it return the TweenInfo
end

ImageButton.MouseButton1Click:Connect(function()
	local currentFrameVisibility = Frame.Visible
	local desiredFrameVisibility = not currentFrameVisibility
--[[ If the Frame is currently invisible, the menu is closed. Since the player
pressed the button, they want to open it, so we can just reverse the value of
Frame.Visible and send that to the ModuleScript so it knows what value it
should be updated to --]]

	local tweenInfo = getTweenInfo()
	
	MenuModule.updateCurrentMenu(Frame, desiredFrameVisibility, tweenInfo)
	print(MenuModule)
	
	currentFrameVisibility = not currentFrameVisibility
	
end)

closeButton.MouseButton1Click:Connect(function()
		local currentFrameVisibility = true
		local desiredFrameVisibility = false
		local tweenInfo = getTweenInfo()
		MenuModule.updateCurrentMenu(Frame, desiredFrameVisibility, tweenInfo)
		print(MenuModule)

		currentFrameVisibility = not currentFrameVisibility

	end)
1 Like

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