- Home /
Using GUIToggle to on/off buttons!
Evening, everyone! I have another question regarding the GUIToggle function. Here's my current code thus far:
var toolSkin: GUISkin;
var toggle = true;
function OnGUI () {
GUI.skin = toolSkin;
//Top Left Button
toggle = GUI.Toggle (Rect(50,400,100,100), toggle, "");
//Middle Button
toggle = GUI.Toggle (Rect(120,440,100,100), toggle, "");
//Top Button
toggle = GUI.Toggle (Rect(120,360,100,100), toggle, "");
//Top Right Button
toggle = GUI.Toggle (Rect(190,400,100,100), toggle, "");
//Bottom Button
toggle = GUI.Toggle (Rect(120,520,100,100), toggle, "");
//Bottom Left Button
toggle = GUI.Toggle (Rect(50,480,100,100), toggle, "");
//Bottom Right Button
toggle = GUI.Toggle (Rect(190,480,100,100), toggle, "");
}
Basically, what this will show is 7 buttons which will change when it is in normal state, hover state and active state. However, once I click on an individual button, all 7 buttons light up at once. How do I prevent this from happening and give me a result whereby clicking an individual button will only cause that button to light up and clicking another button will cause the previous lighted button to off and the current button to light up?
Any help given will be gladly appreciated, thank you very much!
$$anonymous$$aybe I am wrong but you connected the toggle to all of them so why is it surprising that when you click toggle=true and all light up? You need to use different boolean for all because if toggle=true then it activates all. Sorry if I got you wrong
Oh, I see. Sorry! It's my first time getting my basics around. Thanks for pointing that out. Shall do more research on toggles and boolean then. :)
Answer by aldonaletto · Jun 14, 2011 at 12:26 PM
You must have one boolean for each button, and set only the clicked one, clearing all the others. In the script below, only one button is active at any time.
var bt1 = false;
var bt2 = false;
...
var bt7 = false;
// Clears everybody and returns true to help setting the desired one
function setMeOnly():boolean{
bt1 = bt2 = bt3 = bt4 = bt5 = bt6 = bt7 = false;
return true;
}
function OnGUI () {
GUI.skin = toolSkin;
//Top Left Button
if (GUI.Toggle (Rect(50,400,100,100), bt1, "")) bt1 = setMeOnly();
//Middle Button
if (GUI.Toggle (Rect(120,440,100,100), bt2, "")) bt2 = setMeOnly();
...
//Bottom Right Button
if (GUI.Toggle (Rect(190,480,100,100), bt7, "")) bt7 = setMeOnly();
}
If you want to be able to turn the button ON and OFF while keeping the radio button behavior, use this OnGUI function instead:
function OnGUI () {
GUI.skin = toolSkin;
//Top Left Button
bt1 = GUI.Toggle (Rect(50,400,100,100), bt1, "");
if (bt1) bt1 = setMeOnly();
//Middle Button
bt2 = GUI.Toggle (Rect(120,440,100,100), bt2, "");
if (bt2) bt2 = SetMeOnly();
...
//Bottom Right Button
bt7 = GUI.Toggle (Rect(190,480,100,100), bt7, "");
if (bt7) bt7 = setMeOnly();
}
Wow! Thank you very much. This was what I was looking for! Really appreciated it.
Edit: However, is it possible to make it that the same button is able to be toggled on/off yet still retaining this current result?
Do I have to use a different function ins$$anonymous$$d since set$$anonymous$$eOnly clears away all the variables except the one that is currently on?
Or should I use a if and else under the function OnGUI ins$$anonymous$$d?
I'll change the var bt1 = false; to var bt1: boolean = false; first. Then try to get another function boolean in, but I won't get my hopes up. XD
I edited the answer to achieve this behaviour. I left the original one for reference, but presented an alternative OnGUI function which behaves the way you want.
At first sight, both seems to do the same thing, but in the first option the btN variable was not updated directly by GUI.Toggle - it only was set if GUI.Toggle returned true, so you could not turn it OFF. In the second option, GUI.Toggle could turn the btN variable ON and OFF, but if it was turned ON the btN=set$$anonymous$$eOnly() part did the "radio button" thing, resetting everybody and keeping the btN button ON.
NOTE: By the way, if this answer solved your problem, please click the green button to change its status to SOLVED - it usually helps other guys needing something similar.
Yikes! I'm sorry. I didn't know about the green button! Thanks for the explanation too! :)
Let's explain the obscure points:
The sintax:
The if statements were written in a concise form: since the bt variables are boolean, if (btN) does the same as if (btN==true) ; and since there is only one instruction to be executed when the if is true, we don't need to surround the instruction with curly braces (we should use curly braces if there were more than one instruction in the if ), so the line:
if (bt7) bt7 = set$$anonymous$$eOnly();
does the same as:
if (bt7==true){
bt7 = set$$anonymous$$eOnly();
}
The function set$$anonymous$$eOnly uses a C style trick:
bt1 = bt2 = bt3 = bt4 = bt5 = bt6 = bt7 = false; return true;
in javascript, C, C# and similar languages, every assignment lets the value assigned as a result, which can be assigned to other variables. In this case, the assignment bt7 = false produced the false result, which was assigned to bt6; this assignment again produced a false value, which was assigned to bt5, and so on. Finnally, the function set$$anonymous$$eOnly ends returning true in order to simplify things to us - since it cleared all bt variables, we will use this result to set again the variable we want to be true.
The "turn on only" approach:
if (GUI.Toggle (Rect(50,400,100,100), bt7, "")) bt7 = set$$anonymous$$eOnly();
The idea here is: "if this button was clicked, clear all buttons and set this one" , thus we just check the Toggle button; if it's pressed, the function set$$anonymous$$eOnly clears everybody and we use its result (true) to set the variable relative to the button - bt7 in this case. Notice that we only alter the values when some button is turned on; when it's turned off, the variables are not altered, and thus the button doesn't change state (the current state of each button is defined by its bt variable).
The "turn on or off" alternative:
bt7 = GUI.Toggle (Rect(120,440,100,100), bt7, ""); if (bt7) bt7 = set$$anonymous$$eOnly();
The idea here is: "store the new state of this button; if it was turned on, clear all other buttons" . We do this by first storing the button status in its bt variable; if it was turned on, we clear all buttons with the set$$anonymous$$eOnly function and restore its bt variable . Notice that in this case the button keeps the state we set last, because it was directly stored in its bt variable; as in the other case, we only adjust the other variables with set$$anonymous$$eOnly when this button is turned on.
Answer by Anxo · Jun 14, 2011 at 11:26 AM
Byerdelen is right, one toggle = one boolean. So if you are clicking on any of your buttons you are changing the same boolean "toggle".
You could create 7 booleans and link each button to its own boolean like so
private var toggle1 : boolean = false; private var toggle2 : boolean = false;
toggle1 = GUI.Toggle (Rect(10,10,100,100), toggle1, "");
toggle2 = GUI.Toggle (Rect(110,110,100,100), toggle2, "");
Answer by jahroy · Jun 14, 2011 at 05:15 PM
Here's what I would do:
I would create a new class to represent a custom toggle button.
The new class would keep track of the button's position, label, current state, and maybe even the name of the style it uses.
I would then create an array of these objects and iterate over that array to draw the buttons.
class ActionButton
{
var styleName : String; // name of custom style in GUI Skin
var isSelected : boolean; // is the toggle button on or off
var label : String;
var position : Rect; // where to draw this button on the screen
}
/* an array of buttons that you can populate in the inspector */
var buttonList : ActionButton [];
function OnGUI ()
{
for ( var i = 0; i < buttonList.length; i ++ ) {
var butt = buttonList[i];
butt.isSelected =
GUI.Toggle(butt.position, butt.isSelected, butt.label, butt.styleName);
if ( butt.isSelected ) {
print("This butt is turned on: " + butt.label);
resetOtherButtons(i);
}
}
}
function resetOtherButtons ( ignoreThisNumber )
{
for ( var i = 0; i < buttonList.length; i ++ ) {
if ( i != ignoreThisNumber ) {
buttonList[i].isSelected = false;
}
}
}
Thanks for the reply but this is still tough for me to grasp hold of. I will probably start off by reading through tutorials to define what a class is. But really, thanks for taking time off to answer this question!
No problem. I just pasted it from another answer.
It basically does the same thing as the other answers.
Using classes is a great way to organize and re-use your code. Using classes as public variables in your script allows you to edit their properties in the Inspector, which can be very handy.
For example, using the code above you could position each ActionButton by changing the value of its position in the Inspector. You could tweak these values while playing your game to get your button exactly where you want it.
The other key concept is the use of arrays. To create 7 buttons using the code above you can expand the variable named "Button List" in the Inspector and set its size to 7. Then you'll see seven different elements whose values you can adjust.
For a more simple approach you could just declare 7 different ActionButtons and forget about arrays for now:
var b1 : ActionButton;
var b2 : ActionButton;
var b3 : ActionButton;
var b4 : ActionButton;
b1.isSelected = GUI.Toggle(b1.position, b1.isSelected, b1.label);
if ( b1.isSelected ) {
performButtonOneAction();
}
if ( b2.isSelected ) {
performButtonTwoAction();
}
. . .
. . .
Okay. I've tried using your code and here's what I've done.
class ActionButton { var toggle: String; //Name of custom style in GUI Skin var isSelected: boolean; //Is the toggle button on or off var label: String; var position:Rect; //Where to draw this button on the screen }
/ An array of butons that you can populate in the inspector /
var buttonList : ActionButton []; var b1: ActionButton; var b2: ActionButton; var b3: ActionButton; var b4: ActionButton; var b5: ActionButton; var b6: ActionButton; var b7: ActionButton; var toolSkin: GUISkin;
function OnGUI () {
GUI.skin = toolSkin;
for (var i = 0; i < buttonList.length; i ++) {
var b1 = buttonList[i];
b1.isSelected = GUI.Toggle(b1.position, b1.isSelected, b1.label,b1.toggle);
if (b1.isSelected)
{print("This butt is turned on: " + b1.label);
resetOtherButtons(i); }
var b2 = buttonList[i];
b2.isSelected = GUI.Toggle(b2.position, b2.isSelected, b2.label, b2.toggle);
if (b2.isSelected)
{print("This butt is turned on: " + b2.label);
resetOtherButtons(i); }
var b3 = buttonList[i];
b3.isSelected = GUI.Toggle(b3.position, b3.isSelected, b3.label, b3.toggle);
if (b3.isSelected)
{print("This butt is turned on: " + b3.label);
resetOtherButtons(i); }
var b4 = buttonList[i];
b4.isSelected = GUI.Toggle(b4.position, b4.isSelected, b4.label, b4.toggle);
if (b1.isSelected)
{print("This butt is turned on: " + b4.label);
resetOtherButtons(i); }
var b5 = buttonList[i];
b5.isSelected = GUI.Toggle(b5.position, b5.isSelected, b5.label, b5.toggle);
if (b5.isSelected)
{print("This butt is turned on: " + b5.label);
resetOtherButtons(i); }
var b6 = buttonList[i];
b6.isSelected = GUI.Toggle(b6.position, b6.isSelected, b6.label, b6.toggle);
if (b6.isSelected)
{print("This butt is turned on: " + b6.label);
resetOtherButtons(i); }
var b7 = buttonList[i];
b7.isSelected = GUI.Toggle(b7.position, b7.isSelected, b7.label, b7.toggle);
if (b7.isSelected)
{print("This butt is turned on: " + b7.label);
resetOtherButtons(i); }
}
}
function resetOtherButtons ( ignoreThisNumber ) { for ( var i = 0; i < buttonList.length; i ++ ) {
if ( i != ignoreThisNumber ) {
buttonList[i].isSelected = false;
}
}
}
However, the problem I had was that my buttons don't appear when I click play on the game screen. Was it something that I've failed to link?
You're drawing 7 buttons on top of each other every time you go through the for loop. So you're drawing 49 buttons in the same rectangle.
Also, if you didn't set the position property of each button in the inspector they will be drawn using an un-initialized Rectangle as their position. In other words you'd be drawing 49 buttons that start at screen coordinates (0,0) with a width and height of zero.
Replace everything inside the body of your for loop with this:
var b = buttonList[i];
b.isSelected = GUI.Toggle(b.position, b.isSelected, b.label);
if ( b.isSelected ) {
print("This butt is turned on: " + b.label);
resetOtherButtons(i);
}
$$anonymous$$ake sure you go to the Inspector and set the size of the array of ActionButton objects to 7. Otherwise you're code won't get executed because buttonList.length will equal zero.
I'm trying your answer at the moment, and see if it works out for $$anonymous$$e! fingers crossed
P.S: I used the "Your answer" box below. I typed my comments in there, then copy and paste and brought it over.
Edit: Ooh, it worked! Thank you very much as well. I would actually have chosen your answer and Aldonaletto's answer as the correct answers but I could only choose one. So I chose Aldonaletto's answer as the correct option since it was easier to me at first, and I thought it would help if beginners attempt this type of coding as well. Then they could use yours once they've familiarized themselves with the basics. Hope you don't $$anonymous$$d!
Double Edit: Oh, you can put > in front of your comments before you post it so that it looks formatted. If it doesn't, just use the above solution. :)
Answer by matheus_cubic · Jul 25, 2013 at 02:19 PM
Hi guys, I may be out of date, but I run into this problem as well and come up with a simple ideia that I want to share with you..
int toggleGrid(int currentSelected, string [] selectionOptions) {
int index = 0;
int selected = currentSelected;
foreach (string oneOption in selectionOptions) {
if (GUILayout.Toggle(currentSelected == index, oneOption)
&& currentSelected != index) {
selected = index;
}
++ index;
}
return selected;
}
and then use like this:
selectedOne = toggleGrid(selectedOne, new string[]{"option1", "option2", "option3", "option4"});
I know you can use the selection grid option for the same purpose (GUILayout.SelectionGrid(selectedOne, new string[]{"option1", "option2", "Option3", "Option4"}, 1, "toggle");)
But I needed something that I could modify at my will, so I can add some features..(enable/disable individual option, for example)
That's it =)
Your answer
Follow this Question
Related Questions
Whats wrong with my GUI.Toggle? 2 Answers
GUISkin & Scripting 2 Answers
Problem with icon in GUISkin 0 Answers