local buttonsArray = {}
for i, v in ScreenGui.Chassis.TopMiddleBar:GetChildren() do
if v:IsA("TextButton") then
buttonsArray[v.Name] = v
end
end
for i, v in ScreenGui.Chassis.BottomMiddleBar:GetChildren() do
if v:IsA("TextButton") then
buttonsArray[v.Name] = v
end
end
something.SomeEvent:Connect(function()
if buttonsArray["Move"]:GetAttribute("selected") == true then
-- do stuff
elseif buttonsArray["None"]:GetAttribute("selected") == true then
-- do other stuff
end
end)
The script in question is in starterCharacterScripts and sadly cannot be moved to StarterGUI.
This is what my hierarchy looks like:
Here’s what the localScript looks like that’s under “chassis”
local buttonsArray = {}
for i, v in script.Parent.TopMiddleBar:GetChildren() do
if v:IsA("TextButton") then
table.insert(buttonsArray, v)
end
end
for i, v in script.Parent.BottomMiddleBar:GetChildren() do
if v:IsA("TextButton") then
table.insert(buttonsArray, v)
end
end
for i, v in buttonsArray do
v.MouseButton1Click:Connect(function()
for all, buttons in buttonsArray do
buttons.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
buttons:SetAttribute("selected", false)
end
v.BackgroundColor3 = Color3.fromRGB(200, 255, 200)
v:SetAttribute("selected", true)
end)
end
All I’m trying to achieve is only a single button can be selected at a time. This is what I’ve tried so far. It barely works… and I feel like it can be so so much better, that it basically doesn’t work. Thanks!!!
What’s wrong with it as written? Do you just think the code looks ugly, or is it actually dysfunctional? You have quite an elegant solution as is imo. I have a script written to do the same thing, and your code is much more compact than mine…
All I’d add is that the modifying the selected attribute might be unnecessary, which you do with buttons:SetAttribute("selected", false) and v:SetAttribute("selected", true). I believe it’s used to determine the button’s color (between the values you specify for the button’s selected and unselected states), but since you’re changing the color manually, the value of selected might be irrelevant.
Thanks for the compliment! Yes, I think it looks ugly and very drawn out, it could be much simpler, I just don’t know how.
You’re right, I can use the color as the value to see if the button is selected. I might implement that and mark your post as the solution if I don’t get anything else in the next 24 hours. Thanks!
It can’t be moved to starter GUI because the GUI for some reason doesn’t get loaded. I think I clicked a setting somewhere and it’s broke
I have this ghetto solution for that issue though
I think it might have to do something with the character never spawning, I turned that setting off.
Anyways… I’ll add that
so, just minor changes, thanks!
Also, what exactly does “continue” do? It’s not giving me any errors, but I’ve never seen it before. Thanks!
Honestly this seems like a code review. But your code seems like it would work just fine, though yeah may not be very pretty (personal opinion). Personally I would turn the selection into a module where you can easily access what’s already registered and know when something is selected.
Then turn the connection, presumably an activator event into something that calls functions, instead of having a single thousand lined function, reduces if statements. So that your methods of buttonsArray["None"] will be easily accessible and organized. Though I don’t know your coding habits or how you organize your code so this is just one of the million examples someone could make of your idea.
For example:
This is the module script, that’s located somewhere.
-- // Variables
local parent = script.Parent
local module = {}
module.__selection = {}
module._previous = nil
module.Current = nil
-- // Not actually important
module._selectionUpdated = Instance.new("BindableEvent")
module.SelectionUpdated = module._selectionUpdated.Event
-- // Constants
local DEFAULT_UNSELECTED_COLOR = Color3.fromRGB(255, 255, 255)
local DEFAULT_SELECTED_COLOR = Color3.fromRGB(200, 255, 200)
-- // Functions & Methods
function module.deselect(child)
module._previous = child
if not child then return end
child.BackgroundColor3 = DEFAULT_UNSELECTED_COLOR
end
function module.select(child)
module.deselect(module.Current)
if child == module._previous then return end
child.BackgroundColor3 = DEFAULT_SELECTED_COLOR
module.Current = child
module._selectionUpdated:Fire(child)
end
-- // This is so you can define which buttons you want only one selected of
function module.registerChildren(children)
for _, child in ipairs(children) do
if not (child:IsA("GuiButton")) then continue end
if (module.__selection[child.Name]) then
warn(`Child with name already registered as {child:GetFullName()}. \n{debug.traceback(nil, 2)}`)
continue
end
module.__selection[child.Name] = child
child.Activated:Connect(function()
module.select(child)
end)
end
end
local function init()
module.registerChildren(parent.TopMiddleBar:GetChildren())
module.registerChildren(parent.BottomMiddleBar:GetChildren())
return module
end
return init()
And this would be that one script that’s doing all the handy work based on selection, also located somewhere:
local above = require(directory.to.whats.above)
local method_holder = {}
method_holder.Move = function()
-- Do stuff ( :
end
method_holder.None = function()
-- // Presumably nothing but y'know ( ::::
end
-- // I think
activation:Connect(function()
-- // I assume this is your do something script
-- // Because nothing is selected, do nothing
if not (above.Current) then return end
local method = method_holder[above.Current.Name]
assert(method, `Non-registered method for selected button {above.Current:GetFullName()}.`)
method()
end)