Search Unity

Toggle Group Hell

Discussion in 'UGUI & TextMesh Pro' started by piginhat, Aug 8, 2019.

  1. piginhat

    piginhat

    Joined:
    Feb 17, 2016
    Posts:
    96
    So I have a container with a ToggleGroup component attached.

    Inside I have two toggles both with the parent ToggleGroup component linked.

    Now when I open the panel that has these toggles I perform a check on a user preference and set the required toggle on which works only while the game is active. Once I restart I get the weirdness that has been dogging me for 3 days now!

    So when the app starts currentMode defaults to true and the mode toggles are set correctly. In the app the user can change mode which will then give a value false and is saved.

    Upon loading I confirm that currentMode has been retrieved and is correctly set to false.

    However when the below code runs the toggle is ALWAYS set to true even though I am passing in the value false?

    Code (CSharp):
    1.  
    2. print("before " + currentMode);  // will print false
    3.  
    4. modeSelectionToggles[0].isOn = currentMode;  // will set the toggle on?
    5.  
    6. print("after " + currentModeOn);  // will still print false
    7.  
    I thought I had found the answer in that I had not at least one toggle.isOn checked in the editor but that was a red herring!

    I now have got it working but seems an awkward way of doing it given we are dealing with bool values!

    I have changed currentMode to be an int and thus can use 0 and 1 as follows:

    Code (CSharp):
    1.  
    2. for (int i = 0; i < modeSelectionToggles.Length; i++) {
    3.  
    4.       if (i == currentMode) {
    5.  
    6.             modeSelectionToggles[i].isOn = true;
    7.        }
    8.        else {
    9.  
    10.              modeSelectionToggles[i].isOn = false;
    11.         }
    12. }
    13.  
    This works but surely is not necessary when the first approach above should work?
     
    Last edited: Aug 8, 2019
  2. Trivium_Dev

    Trivium_Dev

    Joined:
    Aug 1, 2017
    Posts:
    78
    Two things - do you have any event listeners attached to the toggles that might reset their states or do anything that might cause them to toggle incorrectly. In your second code example you set the state of both toggles whereas in the first code example you only set the state of one of them.

    Also in your first code example, the toggle at index 0 would be toggled off if the currentMode value is false (your comment after it mentions "will set the toggle on?" but it won't). However, note that it won't toggle the other toggle on even if your toggle group has the "allow switch off" unchecked. If modeSelectionToggles[1] is off already, you can't set modeSelectionToggles[0] to off as well (assuming modeSelectionToggles[0] is already on).
     
  3. piginhat

    piginhat

    Joined:
    Feb 17, 2016
    Posts:
    96
    Sorry that comment applies on first run. currentMode is set to true as default so on first run it will set the toggle on. My understanding is that you have to have at least one toggle turned on at start in order for the toggling to work.

    I do not have allow switch off checked.

    So as I say when the app starts first time currentMode will be true and so modeSelectionToggles[0].isOn is turned on which I presume then turns modeSelectionToggles[1].isOn off as you cant have them both off?

    The user changes the state of currentMode to false and during the current session the toggles will be set correctly until I close and restart the app.

    So now currentMode is false and the console reflects that. But modeSelectionToggles[0].isOn = currentMode; does not turn off this toggle, it is set to on?

    I do not have any event listeners.

    The second code snippet works but this seems ineffective and to me surely simply by turning one toggle off or on then the other should be the negative state of it?
     
  4. Trivium_Dev

    Trivium_Dev

    Joined:
    Aug 1, 2017
    Posts:
    78
    If you don't have "switch off" checked, then you can't turn off ALL the toggles. Which means if you have two toggles, and one is off and the other is on, you can't turn off the one that is on (in code or in game). It won't automatically turn the other one on. You can test this yourself - if you click the toggle that is already on in your game, it won't turn it off and the other one won't turn on. You have to click the other one, and then the one that was on will turn off and the one you clicked will turn on.

    This is why your second code seems to work while your first one doesn't. If you changed your first code to

    Code (CSharp):
    1. print("before " + currentMode);  // will print false
    2. modeSelectionToggles[0].isOn = currentMode;  // will set the toggle on?
    3. modeSelectionToggles[1].isOn = !currentMode;
    4.  
    5. print("after " + currentModeOn);  // will still print false
    it would work because it would set your second toggle to true/on and will turn the other one off - and if currentMode is true, it will turn on the first toggle and turn off the second.

    As a side note, it's important to always set all toggles to their correct state on start, because if you don't they may be wrong initially. For example, if in the editor you create two toggles and have them on (before playing) and assign them to a toggle group, they will both be on when the game starts. When the user clicks one, that one will turn off. When they click that same toggle again, it will turn on and turn the other off. The user won't ever be able to get back to "both toggles are on" which will seem broken to them.
     
    piginhat likes this.
  5. piginhat

    piginhat

    Joined:
    Feb 17, 2016
    Posts:
    96
    Ah! therein lies my misunderstanding! I thought that if I set one on in code then the other would automatically turn off and vice versa.

    I actually had the code set as you suggest a while back but have so many panels with toggles that go lost in the forest of toggles setup etc!

    I don't want the user to be able to turn off both so that's why I leave allow switch off unchecked and I do a status check and set the toggles states as the panel opens, as in the code example above.

    Thanks for clarifying this...has been driving me up the wall lol.
     
    Trivium_Dev likes this.