Disabling and enabling multiple components

Lets say you have a sprinting system that lets the player press Shift to sprint. Then you have an inventory UI that the player can toggle open and close with E.

When the inventory is open, I want to disable sprinting. So something like:

local inventoryVisible = false
local sprintEnabled = true

local function toggleInventory()
	if inventoryVisible then
		inventoryVisible = false
		sprintEnabled = true
	else
		inventoryVisible = true
		sprintEnabled = false
	end
	inventoryFrame.Visible = inventoryVisible
end

Now you have a leaderboard UI, which the player can press Tab to toggle open and close. Opening the leaderboard also disables sprinting. The leaderboard and inventory can both be visible at the same time.

local inventoryVisible = false
local sprintEnabled = true
local leaderboardVisible = false

local function toggleInventory()
	if inventoryVisible then
		inventoryVisible = false
		sprintEnabled = true
	else
		inventoryVisible = true
		sprintEnabled = false
	end
	inventoryFrame.Visible = inventoryVisible
end

local function toggleLeaderboard()
	if leaderboardVisible then
		leaderboardVisible = false
		sprintEnabled = true
	else
		leaderboardVisible = true
		sprintEnabled = false
	end
	leaderboardFrame.Visible = leaderboardVisible
end

So now when the player opens the leaderboard or inventory independently, the sprinting is enabled and disabled correctly.

But when the player opens both the leaderboard and inventory and then closes either one, the player can sprint with the leaderboard or inventory open.

The simplest solution is to just check if the other UI is open when toggling. But the flaw is scalability. What if I wanted to add other UI that also disables sprinting? Or what if I wanted to disable everything during a cutscene? I’d have to check if all of them are visible before enabling sprinting.

I’m not the best with UI, but here’s what I would do. Instead of having multiple bool values for each GUI, have one int value. Increase the int value when one of the multiple GUIs are opened, and decrease the value if one of the GUIs are closed. if the int value is 0, then no GUIs are opened, and you can sprint.

That is what I though of when I made the post. I currently have something similar implemented in my project.

I have the Visible state of all the UI in a Rodux state.

local sprintEnabled = true

local disableCount = 0
local disableWhen = {
	Inventory = true,
	Leaderboard = true,
}

local function stateChanged(state)
	local uiState = state.UI

	disableCount = 0
	for k, enabled in pairs(uiState) do
		if disableWhen[k] == enabled then
			disableCount += 1
		end
	end

	sprintEnabled = disableCount <= 0
end)

With the disableWhen table, I easily set which UI elements I want the sprint to check and what Visible state they should be in for sprinting to be enabled.

local disableWhen = {
	Inventory = true,
	Leaderboard = false, 
} -- Sprinting is disabled when the leaderboard is not visible. 

This seems to work so far in testing.

1 Like