Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Voting for the Unity Awards are OPEN! We’re looking to celebrate creators across games, industry, film, and many more categories. Cast your vote now for all categories
    Dismiss Notice
  3. Dismiss Notice

Button (used for toggle) gets darker

Discussion in 'UGUI & TextMesh Pro' started by SimRuJ, Sep 19, 2018.

  1. SimRuJ

    SimRuJ

    Joined:
    Apr 7, 2016
    Posts:
    247
    I made my own toggle using a button:

    Code (CSharp):
    1. public void myButtonsOnClick() {
    2.     if(toggled) {
    3.         toggled = false;
    4.         myButton.GetComponent<Image>().color = myButton.colors.normalColor;
    5.     } else {
    6.         toggled = true;
    7.         myButton.GetComponent<Image>().color = myButton.colors.pressedColor;
    8.     }
    9.     //Do more stuff
    10. }
    Normal color: Grey (160,160,160, 255)
    Highlighted color: Grey (160,160,160, 255)
    Pressed Color: Magenta (255,0,255, 255)

    The button looks fine before I press it but after toggling it on with a click and off again with another click the grey is a little bit darker than before.


    Arrow button: What the grey should look like
    Flash button: Darker grey after toggling the button
    The color of the panel that's parenting both buttons doesn't matter, the grey changes even if it's black.

    myButton.GetComponent<Image>().color


    outputs "RGBA(0.627, 0.627, 0.627, 1.000)", which is 160/255 (=0.6274509...), so it should be the same color but it isn't.

    Inspector: click

    Any idea what could cause this? Is there some kind of color "baking" for buttons that's enabled by default?
     
  2. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,833
    Unity Buttons have an animated "Transition", which by default uses different colors to show normal, highlighted, pressed, and disabled states. (These are multiplied into the base color.)

    Note that the "highlighted" state is used both for when you point at the button and for when the button is "selected" (for keyboard/joystick input). After clicking a button, it will usually remain selected until you click on something else, which means it will tend to stay in the "highlighted" state.


    By the way, you know that Unity has its own built-in Toggle class?
     
  3. SimRuJ

    SimRuJ

    Joined:
    Apr 7, 2016
    Posts:
    247
    @Antistone First of all: Thanks for your answer!
    I know, it's a "feature" (feels more like a bug) I've had my fair share of problems with. That's why I set the Navigation of both buttons you can see in the image above to "None". This way a button reverts back to its "Normal" state after hovering over/pressing it, instead of staying in its "Highlighted"/"Pressed" state - which is what my flash button also does but the color's messed up.

    The "arrow up" button on the left is just a normal button that uses the same colors as the flash one and if I hover over it or click it, it reverts back to its normal, grey color. That's why I don't understand why the flash one doesn't. I always set the color back to the "Normal" one and I've even tried setting it directly with
    myButton.GetComponent<Image>().color = Color.grey

    but it's still darker than the normal grey should be.
    I'm aware of that, yes. But there's a different bug with toggles that causes an infite loop if you set its "isOn" value manually (which I would have to do) and changing a button to work as a toggle was faster than dealing with the bug and the workaround to fix it (plus replacing its images).
     
  4. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,833
    By "manually" you mean from script?

    I'm guessing that you got an infinite loop because you put a listener on its OnValueChange event, and that listener assigned to isOn, which caused the event to fire again, causing the listener to be invoked again...

    If that's your issue, you can usually work around it by creating a flag that stops your listener from executing if it's already running; e.g.
    Code (CSharp):
    1.         bool updatingUI;
    2.         public void ClearSlots()
    3.         {
    4.             if (updatingUI) return;
    5.             try
    6.             {
    7.                 updatingUI = true;
    8.                 for (int s = 0; s < slots.Length; ++s)
    9.                 {
    10.                     slots[s].isOn = false;
    11.                 }
    12.             }
    13.             finally
    14.             {
    15.                 updatingUI = false;
    16.             }
    17.         }
    ...but if I'm wrong and you're getting an infinite loop for some other reason, would you mind explaining more? Sounds important to know about.
     
  5. SimRuJ

    SimRuJ

    Joined:
    Apr 7, 2016
    Posts:
    247
    Yes, there's a whole thread about it: You set "isOn" manually, which automatically triggers "onValueChanged" and can then create an infinite loop of them calling each other. There's an easier workaround for that: Set a bool before you access "isOn", then check this bool in your "onValueChanged" method and simply don't do anything if it's set.

    But that's not the issue here. My button works fine as a toggle and I don't even have to know when its "onClicked" is triggered, so I see no reason why I should replace it with an actual toggle. It's just that I don't know why it's getting darker after toggling it once or, to be more exact, why it's staying that way/keeping that darker overlay, even though I am setting the color back to normal.

    Edit: What I just noticed:
    If I long-press on the flash button, it becomes a bright magenta (which it should be) but if I just click on it to toggle it, it turns bright magenta for a split second, then turns a darker magenta and stays that way. So clicking on it is what triggers the darker color.
     
    Last edited: Sep 25, 2018
  6. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,833
    That's what I did in the example above.

    The try...finally structure guarantees that the bool will get cleared when you're done even if something goes wrong in the process (otherwise, an error could leave the flag permanently on, preventing you from reacting to valid input).



    I agree it would be nice if Unity allowed you to change the value in a special way that didn't trigger events, but I wouldn't describe the current behavior as a bug.
     
  7. SimRuJ

    SimRuJ

    Joined:
    Apr 7, 2016
    Posts:
    247
    You just keep turning the toggles off again if they're toggled and not sure why'd you have an array, unless all of your toggles are for the same thing.

    What I did for a toggle in my settings:
    Code (CSharp):
    1. public void ReadSettingsFileInTheBeginning() {
    2.     dontToggle = true;
    3.     if(mode==0) {
    4.         myToggle.isOn = false;
    5.     } else if(mode==1) {
    6.         myToggle.isOn = true;
    7.     }
    8.     dontToggle = false;
    9. }
    10.  
    11. public void OnValueChangedToggled() {
    12.     if(!dontToggle) {
    13.         if(myToggle.isOn) {
    14.             mode = 1;
    15.         } else {
    16.             mode = 0;
    17.         }
    18.     }
    19. }
    If there should be an error with that small bit of code, a toggle that's set to the wrong thing would be the least of my problems.

    Let's then call it "unexpected behavior" (which in the end could be a bug).

    But, like I said, that's not what this thread is about, so back to topic please. Do you know how to fix the color of the button?