Help with Arrays - Check if only 1 is toggled
Hey guys,
I don't know if I'm going about this the right way. Basically I need to be able to click a toggle, and when I click the toggle, I need to change the alpha of a few buttons. I wanted to do it in an Array because I'll be adding more buttons called Slots later
public void ShowAllSlot()
{
GameObject[] buildOptionsFinder = GameObject.FindGameObjectsWithTag("BuildOptions");
buildOptions = new Toggle[buildOptionsFinder.Length];
for (int i = 0; i < buildOptionsFinder.Length; i++)
{
buildOptions[i] = buildOptionsFinder[i].GetComponent<Toggle>();
//Debug.LogError(buildOptions[1]);
if (buildOptions[i].isOn )
{
GameObject[] slotFinder = new GameObject[transform.childCount];
for (int ii = 0; ii < transform.childCount; ii++)
{
slotFinder[ii] = GameObject.Find("Level1Slots").transform.GetChild(ii).gameObject;
Image button = slotFinder[ii].transform.GetChild(0).transform.GetChild(0).transform.GetComponent<Image>();
Debug.LogError("IT SHOULD BE SHOWING NOW");
button.color = Alpha40;
}
}
}
}
I can't seem to figure a way to say :
if (1 out of all buildOptions[i].isOn == true) do this else if (all buildOtions[i].isOn == false) do this
Thanks!
Answer by flashframe · Sep 21, 2015 at 09:36 PM
You could use a bool and a foreach loop to check that at least one of the toggles is selected. Something like this (I haven't tested this code sorry, just writing it from memory).
bool isToggled = false; //declared at the start of your class
foreach(Toggle t in buildOptions){
if(t.isOn){
isToggled = true;
}
}
if(isToggled){
//Do something
}else{
//Do something else
}
isToggled = false;
Answer by Budoray · Sep 22, 2015 at 03:45 AM
I may be misunderstanding your question, but in the event that I'm not, here is an example that uses Linq to show another way to tackle your problem. Your question read to me as if you only wanted to do something if only one true element was in an array and to do something else otherwise. The above for loop runs the risk of changing the toggled flag back to false if the last element happens to be false.
In your case, the test would be more like if(buildOptions.Any(x => x.isOn) ... or if you're just looking for the count to be one and only one, if(buildOptions.Count(x => x) == 1).
using System;
using System.Linq;
public static void Main()
{
var n1 = new bool[3] { true, true, true };
var n2 = new bool[3] { true, false, false };
var n3 = new bool[3] { false, false, false };
if (n1.Any(x => x)) // short for (x => x == true)
{
Console.WriteLine("N1 has at least one that is true");
}
if (n2.Any(x => x))
{
Console.WriteLine("N2 has at least one that is true");
}
if (n3.All(x => !x)) //short for (x => x != true)
{
Console.WriteLine("N3 has none that are true");
}
// Count
var n1TrueCount = n1.Count(x => x);
var n2TrueCount = n2.Count(x => x);
var n3TrueCount = n3.Count(x => x);
Console.WriteLine("N1 True Count: " + n1TrueCount);
Console.WriteLine("N2 True Count: " + n2TrueCount);
Console.WriteLine("N3 True Count: " + n3TrueCount);
//Testing Count
if(n1.Count(x => x) == 3)
{
Console.WriteLine("Do This");
}
}
Just to clarify, my solution doesn't run the risk of setting the flag to false if the last element happens to be false.
No. It won't set it to false. I said it is risky. Using a for loop in the manner you showed is risky and inferred that care must be taken to manage that risk. $$anonymous$$y intent was not to challenge your program$$anonymous$$g ability or style. We all write code a bit differently. $$anonymous$$y apologies if I have offended you.
Thank you for the help! I'm still very new at program$$anonymous$$g so I'm happy to learn a different route. The first answer seems to work for what I need, but if you don't $$anonymous$$d clarifying the risk factor so I can learn from it. Also, the script seems quite complicated lol but I wan't to know more about it. Can you refer me to were I can read up on it?
The risk is that the code uses a foreach loop to set a variable outside the loop with no break or way to exit the for loop until it loops through every item. Again, this isn't necessarily wrong. It's something that you have to be aware of and manage.
Take the code I shared and paste it into dotnetfiddle.net. $$anonymous$$anipulate the code. Try other things with the code. The snippet of code I shared is not what you would use in your code. It only demonstrates how to use linq in a similar manner as a solution to your question. For testing and learning, replace n1, n2, n3 with buildOptions1, buildOptions2, buildOptions3. Once you get a grasp of what's going on with the snippet I shared, then you can go back to your code and change it if you wish.
if(buildOptions.Any(x => x.isOn) // same as if(buildOptions.Any(x => x.isOn == true) { // Do something }
If buildOptions has any toggle (x) such that (=>) toggle.isOn Do something
Does that help? Here's another primer for linq. http://www.dotnetperls.com/linq
Thank you for the information! I've been meaning to learn about Linq! I think I'm starting to get it. Really appreciate it.
@Budoray No offence taken. I appreciate my comment was a bit curt, sorry. I too would like to know the risk if you could clarify.
Your answer
Follow this Question
Related Questions
Custom inspector array issues for loop 0 Answers
Array of Arrays 3 Answers
Crear un arreglo de una clase en otra clase 0 Answers
Simple Code Not Woking 1 Answer