Search Unity

uGUI Graphical Toggle Button

Discussion in 'UGUI & TextMesh Pro' started by pixpusher2, Aug 21, 2014.

  1. pixpusher2

    pixpusher2

    Joined:
    Oct 30, 2013
    Posts:
    121
    Hey all,

    I'm trying to port over my old GUI to the new system. I have a button that toggles graphically between ON state and OFF state each time you press it.

    I tried doing it with the Toggle UI, but it only toggles the button's visibility (no image swap available). The Button UI on the other hand, reverts back to its original state once you release the mouse button.

    Is there an UI component that does graphical toggle, besides me doing function calls and change the image by script? Did I miss something?

    Thanks!
     
  2. ortin

    ortin

    Joined:
    Jan 13, 2013
    Posts:
    221
    There is no such component now and it won't be available in 4.6 final release.
    All you can do now is to use Toggle with "Checkmark" image which covers "Background" image (names are from default Toggle created with Unity menu).
     
    pixpusher2 likes this.
  3. vonchor

    vonchor

    Joined:
    Jun 30, 2009
    Posts:
    249
    nope, doesn't seem like you missed anything.
     
    pixpusher2 likes this.
  4. Tim-C

    Tim-C

    Unity Technologies

    Joined:
    Feb 6, 2010
    Posts:
    2,225
    It's something we will be adding, but it won't be ready for version one. Once the source is available you should be able to see how we do things and add your own.
     
    pixpusher2 likes this.
  5. pixpusher2

    pixpusher2

    Joined:
    Oct 30, 2013
    Posts:
    121
    I see! Thanks for the replies.
     
  6. iewufhe

    iewufhe

    Joined:
    Aug 2, 2013
    Posts:
    11
    Yeah! It would be very nice if unity developers added this in Toggle component or offered another solution. I often need do elements similar this(image below). But in every UI(dfgui, ngui, here) i invent something new. Now I use the crutch: I do function so called "toggleChangedHandler". it runs always when toggle state changed...It simply sets backgrounds alpha of toggle to 0 when toggle changed to active(now Toggle.isOn),and returns background alpha to 255 when toggle changed to inactive.
     

    Attached Files:

  7. vatara

    vatara

    Joined:
    Feb 26, 2010
    Posts:
    22
    I had the same problem, so I wrote a little class that would work around this. It simply disables a graphic when the toggle is enabled. You can use the "checkmark" from the standard toggle as the on state, and just create another image as the off state. Attach this script to the toggle and assign the image you want to hide to the script.

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3.  
    4. [RequireComponent(typeof(Toggle))]
    5. public class ToggleHide : MonoBehaviour {
    6.     public Graphic graphic;
    7.  
    8.     void Start() {
    9.         GetComponent<Toggle>().onValueChanged.AddListener((value) => {
    10.             OnValueChanged(value);
    11.         });
    12.     }
    13.  
    14.     void OnValueChanged(bool value) {
    15.         if (graphic != null) {
    16.             graphic.enabled = !value;
    17.         }
    18.     }
    19. }
     
  8. dval

    dval

    Joined:
    Jul 25, 2012
    Posts:
    24
    @vatara I modified your script, so you can place it on a button, and then drag any GameObject to the inspector.
    Thanks!
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3.  
    4. [RequireComponent(typeof(Button))]
    5. public class ToggleElement : MonoBehaviour {
    6.     private bool visible = false; //show or hide at start
    7.     public GameObject go;
    8.  
    9.     void Start() {
    10.         GetComponent<Button>().onClick.AddListener(() => {
    11.             OnClick();
    12.         });
    13.         OnClick(); //set initial state
    14.     }
    15.  
    16.     void OnClick() {
    17.         visible = !visible;
    18.         go.SetActive(!visible);
    19.     }
    20. }
     
    BEFaughnan likes this.
  9. BEFaughnan

    BEFaughnan

    Joined:
    Oct 4, 2013
    Posts:
    13
    Any word on this becoming a standard feature, yet?

    Its something that is used VERY often. Seems really bizarre that it isn't there. Guess i'll go back to scripting the entire GUI.
     
    Last edited: Apr 21, 2015
  10. Xoduz

    Xoduz

    Joined:
    Apr 6, 2013
    Posts:
    135
    I would like an update from Unity concerning this as well. It seems like a strange oversight to leave out something this basic from the standard UI functionality. Or is it so basic that everyone is expected to write their functionality for this on their own?
     
  11. tmcglinn

    tmcglinn

    Joined:
    Dec 1, 2015
    Posts:
    1
    I've tried writing this:

    Code (CSharp):
    1. /// <summary>
    2.  
    3. /// A Toggle that also sets a gameobject active when the toggle is on, and inactive when the toggle is off.
    4.  
    5. /// </summary>
    6. public class SettingsToggle : Toggle
    And it works fine, but requires a lot of hacking around Unity because a lot of the methods and properties are not defined as virtual; so I need to use the non-type safe reflection method described here http://stackoverflow.com/questions/135443/how-do-i-use-reflection-to-invoke-a-private-method

    In order to call Set(). I also have to switch the Unity editor to debug mode in order to swap out the toggles I already have for the new SettingsToggle, because Unity saw fit to remove that feature from the regular editor in version 5.

    You also have to build a whole new Editor, or find out how to override the ToggleEditor (which I haven't been able to find yet) It seems indeed that UnityEngine.UI is just not built for extending; I'm going to switch to the component listener approach above, even though it is less elegant than what should be possible, if this were a mature GUI library:

    Code (CSharp):
    1. protected override void Set(bool value)
    2. {
    3.     myAddedFeature.SetEnabled(value);
    4.     base.Set(value);
    5. }