Search Unity

Clicking a button leaves it in MouseOver state

Discussion in 'UGUI & TextMesh Pro' started by kingdutka, Dec 11, 2014.

  1. kingdutka

    kingdutka

    Joined:
    Feb 1, 2011
    Posts:
    129
    I'm using an out of the box UI button and all I changed was the "Highlighted Color". When I run the game, the button highlights correctly with mouse over and reverts to normal when mouse leaves but when I click on the button, the highlight color stays on even when the mouse leaves the button area. I have to click "somewhere outside the button area" to get the highlight removed. Is this intentional? Anyone else have this problem?
     
    Firemaw and kyenonline like this.
  2. rakkarage

    rakkarage

    Joined:
    Feb 3, 2014
    Posts:
    683
    ya i just noticed this too
    i guess it is also the selected state
    pressing enter while it is selected will press the button
    but only seems to happen for buttons that have navigation setup or auto
     
  3. kingdutka

    kingdutka

    Joined:
    Feb 1, 2011
    Posts:
    129
    Nice! (Sort of) I set the 'Navigation' to 'None' and the issue auto-resolved. I could see leaving this on for controller-based input but not for mouse or touch-screen inputs. My game is currently PC only and will eventually extend to Android/iOS but none of those use a controller so I'm good with just disabling the Navigation. Thanks!
     
  4. Strom_CL

    Strom_CL

    Joined:
    Nov 17, 2012
    Posts:
    115
    Saw this today too, filed a report for it. My project is a mobile game so its not a super annoying issue to disable nav, but I imagine anyone doing PC or Console development needs to have navigation enabled. Hopefully this is a quick easy fix that will make it in the next version. :)
     
  5. Tim-C

    Tim-C

    Unity Technologies

    Joined:
    Feb 6, 2010
    Posts:
    2,225
    We don't have seperate visual states for selected and ''highlighted' currently. We changed this behaviour in 4.6.1 so that selection and highlighitng work together (there are issues when they don't). We may add some extra visual states for this in the future. Some games do this, others just reuse the same state (what we are currently doing)
     
    ModLunar and lermy3d like this.
  6. beeci

    beeci

    Joined:
    Jan 17, 2013
    Posts:
    2
    I have a checkbox in settings for getting into controller mode. Wrote a script that just modifies the Navigation mode of buttons upon changing the checkbox value - this way works well with controllers and keyboard/mouse too.
     
    ModLunar and newbee05 like this.
  7. URocks

    URocks

    Joined:
    May 1, 2014
    Posts:
    159
    Hi beeci, can you please share your setup in some simple scene? I have also the problem

    Thank you very much
     
  8. raiden

    raiden

    Joined:
    Feb 8, 2009
    Posts:
    333
    @larex39, I know this is pretty old, but I just ran across this issue today, and got some help with how to correct this properly.

    First, I want to thank NCarter form the IRC channel for his help with this.

    What you'll need to do is provide some code that exposes to methods to use for triggering the PointerEnter and PointerExit trigger events on your button.

    I already set these triggers up for my button animations, and inside this code which animates my buttons, I also set the sprites of the SpriteState accordingly, so I resolve the "highlighted" sprite stuck issue.

    Here is the code: (Note, I this is actually for animating the button, but it also sets the sprites for the SpriteState as well)

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using UnityEngine.UI;
    4.  
    5. [RequireComponent(typeof(Animation))]
    6. public class ButtonAnim : MonoBehaviour
    7. {
    8.     // exposed fields
    9.     [SerializeField]private AnimationClip hoverButtonAnim;
    10.     [SerializeField]private AnimationClip exitButtonAnim;
    11.  
    12.     // private fields
    13.     private Animation myAnim;
    14.     private Button btn;
    15.     private Sprite normalSprite;
    16.     private Sprite hoverSprite;
    17.     private SpriteState st;
    18.  
    19.     void Start()
    20.     {
    21.         myAnim = GetComponent<Animation>();
    22.         btn = GetComponent<Button>();
    23.         myAnim.playAutomatically = false;
    24.         normalSprite = GetComponent<Image>().sprite;
    25.         hoverSprite = btn.spriteState.highlightedSprite;
    26.         st = new SpriteState();
    27.     }
    28.  
    29.     public void OnButtonAnimOver()
    30.     {
    31.         myAnim.clip = hoverButtonAnim;
    32.         myAnim.Play();
    33.         st.highlightedSprite = hoverSprite;
    34.         btn.spriteState = st;
    35.     }
    36.  
    37.     public void OnButtonAnimExit()
    38.     {
    39.         myAnim.clip = exitButtonAnim;
    40.         myAnim.Play();
    41.         st.highlightedSprite = normalSprite;
    42.         btn.spriteState = st;
    43.     }
    44. }
    So this is like a "combo" script, so you'll need animation clips for the SerializedFields hoverButtonAnim, and exitButtonAnim, but the actual fix is when the Sprite's are cached in the Start method, and then applied in the OnButtonAnimOver() & OnButtonAnimExit().

    So to use this:
    • Set your Button Transition to Sprite Swap, drag your Highlighted, Pressed and Disabled sprites in
    • Add the EventTrigger component, and Add the PointerEnter & PointerExit trigger events to this
    • Add this script to your UI Button
    • Drag your button animation clips in to the exposed fields on the ButtonAnim script
    • Drag the ButtonAnim script to the PointerEnter trigger slot, drop down the method selector and from the script ButtonAnim, select the method, OnButtonAnimOver
    • Drag the ButtonAnim script to the PointerExit trigger slot, drop down the method selector and from the script ButtonAnim, select the method, OnButtonAnimExit
    What you should see is that when you hover over your button, it will animate and change to the Hover sprite, and when you exit the button, the exit animation will play, and your sprite will return to the Normal Sprite.

    Hope that helps others out :)

    -Raiden
     
  9. SuperUltraHyper

    SuperUltraHyper

    Joined:
    Sep 7, 2015
    Posts:
    112
    Also, if you mouse down inside the button and then leave the button it will stay in the highlighted state even though the action isn't registered until mouse up. :(
     
    ModLunar likes this.
  10. Rodolfo-Rubens

    Rodolfo-Rubens

    Joined:
    Nov 17, 2012
    Posts:
    1,197
    Any news on that?
     
    Malkyne likes this.
  11. Malkyne

    Malkyne

    Joined:
    Nov 18, 2009
    Posts:
    39
    Let's look at the most rudimentary example:

    A Tale of Two Highlights
    1. Create two default buttons, and move them so you can see both of them.
    2. Click on the first button.
    3. Mouse over the second button.
    There are two fundamental problems, here:
    1. When you click on the first button, and the highlight sticks after mousing away, the user perceives this as a bug. It looks sloppy and unprofessional.
    2. When you mouse over the second button, you now have two items highlighted. What does that even mean? It's bad information.
    This is not good default behavior.

    The common solution to this is to set Navigation to "None" on all of these buttons for desktop applications. But that's a bad solution for multiple reasons. Here are two that I have run into:
    1. An application may be intended to run on multiple platforms (including consoles).
    2. A desktop application may actually want to use the selected state legitimately for Tab navigation in a form.
    On top of that, there seem to be some edge-conditions where the developer's intentions are not being respected, even when Navigation is set to "None". For example:
    1. Dropdowns are always highlighted after making a selection, regardless of the Navigation setting.
    2. Mobile platforms sometimes leave buttons in their highlighted state after pressing them, regardless of the Navigation setting.
    Splitting these into two states (much as CSS separates :hover from :focus) would make it much easier to provide robust UI behavior on a wide variety of platforms. Though, because they are not necessarily mutually-exclusive states, I can appreciate that it might be a pain-in-the-neck to shoe-horn this into Unity's current Selectable implementation.

    Like Rodolfo, I'm curious if there has been any progress on this front, or if it has slipped through the cracks. If it's going to stay the way it is, in the long run, it would be useful to know that. I may have to tidy up my mess of workarounds, and share it with people, because I know I'm not the only one fighting with this.
     
  12. IzzySoft

    IzzySoft

    Joined:
    Feb 11, 2013
    Posts:
    376
    i kinda like what i made for my custom UI, which has a state called Focused. :)

     
    Rodolfo-Rubens likes this.
  13. Alverik

    Alverik

    Joined:
    Apr 15, 2016
    Posts:
    417
    As a noob working on a controller only setup, I would highly appreciate if you do share your work arounds. I've been having an specially bad experience with this issue when I disable and re-enable UI menus. Whatever button was highlighted when the menu was disabled stays that way when I re-enable the menu. Which not only looks terrible, but plainly breaks the menu's functionality...
     
    Last edited: Dec 27, 2016
    ModLunar and Malkyne like this.
  14. sebastiansgames

    sebastiansgames

    Joined:
    Mar 25, 2014
    Posts:
    114
    I can't believe this is still not fixed. Really guys??? I'm tearing my hair out trying to make a frickin button work?

    I have a slider -- when you mouse over the handle the knob fades in so you can see it via button state. So far so good. But in automatic navigation, when you release the handle (mouseup), the state doesn't change and the handle is still active. I am not using keyboard controls and do not CARE about keyboard controls.

    If I try to set navigation to 'none' -- then the knob state changes to 'mouseoff' and my knob disappears even though i still have mousedown and am scrubbing back and forth with it. it only turns on when the mouse is directly over the knob. So imagine sliding a knob back and forth and it's flickering on and off because the mouse pointer moves back and forth over it. Even thought the state *should* still be down/active.

    Arrrrgggg

    I've tried to override manually with an event so that on mouseup on the knob i directly invoke:
    EventSystem.current.SetSelectedGameObject(null);

    But apparently putting an event trigger on a slider handle makes the slider handle stop sliding. Brilliant guys.

    I'm just in awe I'm having so much trouble with such simple functionality when like 15 years ago we were doing this in flash blindfolded.
     
  15. Hyphasol

    Hyphasol

    Joined:
    Jun 13, 2014
    Posts:
    7
    After wasting a few hours trying to make this work decently i simply deleted the EventSystem and made my own. Incredibly disappointed in Unity devs considering my first coding experience was making my own GUI with more features than those i was trying to replicate in Unity.
     
    ModLunar, KCAR, TooManySugar and 4 others like this.
  16. GrooGadgets

    GrooGadgets

    Joined:
    Apr 2, 2009
    Posts:
    71
    Yes I agree this situation is totally insane. My game GUI was working fine until a week ago when this problem started to occur for no apparent reason. I can't find a suitable way around it since I am targeting mobile and Apple TV. Turning off navigation on every button in my game is just crazy...
     
    ModLunar, TooManySugar and Alverik like this.
  17. Hexcedra

    Hexcedra

    Joined:
    Dec 31, 2016
    Posts:
    1
    There seem to be an even worse bug that happens when you change panel on a button click in the UI and the highlighted button is set to disable. When you re-enable the button, it is reset back to "highlighted" for some reason, despite not being the selected control. So not only do you have 2 selected buttons if you hover/use navigation keys on another button, but this bug actually can't be bypassed by setting navigation to "None".

    And to add insult to injury, this bug is displayed in their own Live Session tutorial on UIs without even being addressed:
    https://unity3d.com/fr/learn/tutori...ce-ui/polishing-your-game-menu?playlist=17111
    You can see it very briefly at 21:36 to 38.

    Might have been me doing something wrong, but I just can't get rid of it.
     
    ModLunar and TooManySugar like this.
  18. edredar

    edredar

    Joined:
    Jul 26, 2012
    Posts:
    58
    Have the same issue. It began to occur since 5.4.2 patch 3 for sure, maybe patch 1 or 2. On initial release of 5.4.2 everything works fine. However, I've tried 5.5.0p3, and this behaviour is still present. Hope Unity guys can explain what happened.
     
    Syzo and Artifact-Jesse like this.
  19. Artifact-Jesse

    Artifact-Jesse

    Joined:
    May 5, 2013
    Posts:
    5
    This is super frustrating. Unity, can we get a straight answer as to whether you even consider this a bug? Because it is a bug.
     
  20. Firoball

    Firoball

    Joined:
    Aug 6, 2015
    Posts:
    62
    I have the same problem.
    To me it clearly appears to be a bug with highlighted, as the behaviour is not logical in any way.
    The only workaround I found was setting the highlight color identical to normal color. This is not a very good solution however...
     
  21. TheWanderingBen

    TheWanderingBen

    Joined:
    Nov 3, 2015
    Posts:
    98
    Yep, same issue here. My workaround (hopefully only until this is fixed?) is to remove all listeners on my button after it's clicked, instead of disabling it:
    Code (CSharp):
    1. continueButton.onClick.AddListener( () => { continueButton.onClick.RemoveAllListeners(); continueButtonCall.Invoke(); });
    It's a bit specific, since I create a new call every time I re-enable my buttons, but it's an okay solution for now if anybody is in the same boat.

    Has anybody created an Issue Tracker report for this? I would vote for it, but I can't find any while searching. If nobody's made one, I can do it later -- just want to make sure I'm not dividing our votes :)
     
    Alverik likes this.
  22. edredar

    edredar

    Joined:
    Jul 26, 2012
    Posts:
    58
    Looks like when you make the button interactable again, it sets button not to Normal state, but to the state, in which the button was before making it non-interactable.

    Edit:
    Surpassed this bug by using WaitForSeconds. I added CanvasGroup to my group of buttons, then when I want to disable one button - I disable blocksRaycasts of this CanvasGroup, wait for a fraction of second, do my stuff enabling/disabling buttons, and then enable blocksRaycasts back. It is a very ugly solution, but it works.
     
    Last edited: Feb 11, 2017
    Firoball and Alverik like this.
  23. TheWanderingBen

    TheWanderingBen

    Joined:
    Nov 3, 2015
    Posts:
    98
    I've run into a case of this bug that I can't solve with my work-around. Ah well. I could create another hack, but I believe many people will encounter this issue (especially beginners) so it's important for the Unity team to create a robust fix.

    I've created a simple test scene to demonstrate the problem and reported it via Unity's built-in "Report a Bug..." system. I'll update when I see it on Issue Tracker. This is my first time doing this, so please let me know if there's anything else I should do :)

    Edit: FWIW, Unity just sent me an email for their FogBugz tracking system. My bug is Case 880781. You can view it here, but it doesn't look like we can vote on it yet.
     
  24. TheWanderingBen

    TheWanderingBen

    Joined:
    Nov 3, 2015
    Posts:
    98
    Apparently my bug was a duplicate of another, woohoo! Somebody reported this on 2017-02-02. There is an Issue Tracker for it here. Please vote for it, because it's the only way to bump it in their priority!
     
    x4000 likes this.
  25. Firoball

    Firoball

    Joined:
    Aug 6, 2015
    Posts:
    62
    Wow, that did the trick. Thank youso much.

    I was already using the CanvasGroup approach for smooth fading across different menus, but I was setting .interactable and .blockRaycasts without delay.
    I now added a Coroutine and a minimum wait time after I set .blocksRaycasts = false and it appears to work just fine.

    In case someone needs some sample I attached my UIFader component.

    Note:
    It is programmed in a rather defensive way, so it might look strange that there seem to be superfluous settings for the CanvasGroup. This is done to be prepared for any weird transition state the CanvasGroup might be in, when being triggered by event.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. namespace Game.UI
    5. {
    6.     [RequireComponent(typeof(CanvasGroup))]
    7.     class UIFader : MonoBehaviour
    8.     {
    9.         [SerializeField]
    10.         private float m_fadeSpeed = 4.0f;
    11.         [SerializeField]
    12.         private bool m_showOnStart = false;
    13.  
    14.         private CanvasGroup m_canvasGroup;
    15.         private bool m_fadeOut = false;
    16.         private bool m_fadeIn = false;
    17.  
    18.  
    19.         void Awake()
    20.         {
    21.             m_canvasGroup = GetComponent<CanvasGroup>();
    22.             if (m_showOnStart)
    23.             {
    24.                 Enable();
    25.             }
    26.             else
    27.             {
    28.                 Disable();
    29.             }
    30.         }
    31.  
    32.         void Update()
    33.         {
    34.             if (m_fadeOut)
    35.             {
    36.                 m_canvasGroup.alpha = Mathf.Max(m_canvasGroup.alpha - (m_fadeSpeed * Time.deltaTime), 0.0f);
    37.                 if (m_canvasGroup.alpha <= 0.0f)
    38.                 {
    39.                     m_fadeOut = false;
    40.                     Disable();
    41.                 }
    42.  
    43.             }
    44.  
    45.             if (m_fadeIn)
    46.             {
    47.                 m_canvasGroup.alpha = Mathf.Min(m_canvasGroup.alpha + (m_fadeSpeed * Time.deltaTime), 1.0f);
    48.                 if (m_canvasGroup.alpha >= 1.0f)
    49.                 {
    50.                     m_fadeIn = false;
    51.                     Enable();
    52.                 }
    53.  
    54.             }
    55.         }
    56.  
    57.         private void Enable()
    58.         {
    59.             m_canvasGroup.alpha = 1.0f;
    60.             m_canvasGroup.interactable = true;
    61.             m_canvasGroup.blocksRaycasts = true;
    62.         }
    63.  
    64.         private void Disable()
    65.         {
    66.             m_canvasGroup.alpha = 0.0f;
    67.             //m_canvasGroup.blocksRaycasts = false;
    68.             //m_canvasGroup.interactable = false;
    69.             StartCoroutine(DelayedDisable());
    70.         }
    71.  
    72.         public void Show(bool immediately)
    73.         {
    74.             //m_canvasGroup.blocksRaycasts = false;
    75.             //m_canvasGroup.interactable = false;
    76.             m_fadeOut = false;
    77.             if (immediately)
    78.             {
    79.                 Enable();
    80.             }
    81.             else
    82.             {
    83.                 m_fadeIn = true;
    84.                 StartCoroutine(DelayedDisable());
    85.             }
    86.  
    87.         }
    88.  
    89.         public void Hide(bool immediately)
    90.         {
    91.             //m_canvasGroup.blocksRaycasts = false;
    92.             //m_canvasGroup.interactable = false;
    93.             m_fadeIn = false;
    94.             if (immediately)
    95.             {
    96.                 Disable();
    97.             }
    98.             else
    99.             {
    100.                 m_fadeOut = true;
    101.                 StartCoroutine(DelayedDisable());
    102.             }
    103.         }
    104.  
    105.         //Work around button highlighting bug
    106.         private IEnumerator DelayedDisable()
    107.         {
    108.             m_canvasGroup.blocksRaycasts = false;
    109.             yield return new WaitForSeconds(0.01f);
    110.             m_canvasGroup.interactable = false;
    111.         }
    112.     }
    113. }
    114.  
     
    Ouro17 and Alverik like this.
  26. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Good gravy, how is it 2017 and this issue still hasn't been fixed?

    There is just no way this behavior can be considered correct:



    (If the forum refuses to load that animated GIF, you can see it here.)

    I'm not doing anything tricky here. There is no code involved. It's just three buttons, each set to turn purple when pressed and green when highlighted.

    And as you can see, as soon as you click one and then mouse over something else, it appears that there are two buttons highlighted.

    I can't show this to my client. He'll say it's a bug. If we shipped, his users would say it's a bug. It makes no sense to have two buttons highlighted at once — which one is the real current button? Who knows?

    A quick web search shows gazillions of Unity devs confused by this problem. The most common solution is to turn Navigation off. But we need Navigation in this project, as people should be able to navigate the menus using a game controller (as well as a mouse).

    I don't see how this is so hard — if I navigate with the keyboard or gamepad, it highlights the next control and un-highlights the old one. But if I use the mouse, it highlights the next control without un-highlighting the old one. That is Just Plain Wrong. Now I've got to found a workaround, of which there appear to be many but each with their own issues. (Except throwing out EventSystem entirely and rolling our own that doesn't suck, but that has the issue of costing way more than I wanted to spend on a freaking menu.)

    Anybody who follows me knows that I rarely rant about things... generally I love Unity. But this is just awful, particularly because it's been known since version 4.6. C'mon guys... what's the deal?
     
    BloopTrangle, skwsk8, x4000 and 2 others like this.
  27. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    OK, since everybody else has their own hacky work-around for this bug, here's mine.

    Code (CSharp):
    1. // Work-around for Unity's failure to deselect the last-clicked UI
    2. // element when it highlights something else.  See:
    3. // https://forum.unity3d.com/threads/285167/
    4.  
    5. using UnityEngine;
    6. using UnityEngine.EventSystems;
    7. using UnityEngine.UI;
    8.  
    9. public class HighlightDesuckifier : EventTrigger {
    10.    
    11.     public override void OnPointerEnter( PointerEventData data ) {
    12.         Selectable selectable = GetComponent<Selectable>();
    13.         if (EventSystem.current.currentSelectedGameObject != gameObject && selectable.interactable) {
    14.             // Somebody else is still selected?!?  Screw that.  Select us now.
    15.             selectable.Select();
    16.         }
    17.     }
    18.    
    19. }
    You add this script to every button in the scene, and now when you mouse over one of them, the last-clicked button gets unhighlighted. Works with both keyboard and mouse navigation (as long as you don't do both at once — if the mouse is over something it will remain highlighted even as you select something else with the keyboard).

    I suspect there are further issues lurking here somewhere, but this certainly seems better than the default behavior.
     
  28. GreatDane

    GreatDane

    Joined:
    Oct 1, 2015
    Posts:
    1
    I had this problem too. I put my buttons on a panel under another panel with a CanvasGroup and fade it when a button is clicked. When I restore the panel the button is still highlighted.

    I found that disabling the button script resets it so I wrote a 'reset' script and added it to second OnClick action, after the action that the button calls as its main function.

    Add this script to the button and add another OnClick action, drop the button into the OnClick Object and select ResetState as the method to call. Make it a prefab so you do it once.

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3.  
    4. namespace Assets.Scripts
    5. {
    6.     public class ButtonReset : MonoBehaviour
    7.     {
    8.         private void Awake()
    9.         {
    10.             _button = GetComponent<Button>();
    11.             if (_button != null) return;
    12.             Debug.Log("ButtonReset:Awake - Couldn't find the _button.");
    13.         }
    14.  
    15.         public void ResetState()
    16.         {
    17.             Debug.Log("button name is " + _button.gameObject.name);
    18.  
    19.             _button.enabled = false;
    20.             _button.enabled = true;
    21.  
    22.         }
    23.  
    24.         private Button _button;
    25.     }
    26. }
     
    mjbcfc and GuardianWorld like this.
  29. RussellWilson

    RussellWilson

    Joined:
    May 14, 2017
    Posts:
    1
    I declare a 'Transform myButton;' and get myButton = GameObject.Find("my_UI_Button");

    Then use myButton.GetComponent<Button>().enabled = false; and the same = true; -- this works also, but you must use both the false and true settings
     
  30. jwvanderbeck

    jwvanderbeck

    Joined:
    Dec 4, 2014
    Posts:
    825
    Really embarrassing that this is still an issue. Has no one at Unity ever seen how a UI button typically works? These aren't radio buttons, but that is essentially how they are acting.

    2.5 years and still no fix for a very basic rudimentary thing :(

    A standard push button typically works like this:
    1) A base color or graphical state
    2) A mouse enter state
    3) A mouse down or pressed state (this is often an inversion of the 3d look making the button look pushed in)
    4) Optionally a "selected" state which is used for keyboard style interaction, this is often a dashed border on the button to show that it is the active button that will be pressed if you press space/enter

    When using a mouse, the "selected" state isn't even a thing. The button should highlight when the mouse enters it, be depressed when the user clicks, then return to the highlighted state when the user releases the button, then finally return to the base state when the mouse leaves the button.

    In Unity the buttons act like radio buttons. You click them and they stay pressed. If you click another button, then the first one is unpressed and the new one is pressed. Those are radio buttons not push buttons!
     
  31. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    They're not staying pressed — they're staying selected. (Which for many setups, looks the same as highlighted.)

    But yeah, it's an embarrassing mess. If something was selected with the mouse, it should be deselected when the mouse leaves. Or at least — like my workaround above — when we mouse-enter something else, and therefore highlight it, we should deselect whatever was previously selected.
     
    Rodolfo-Rubens and Alverik like this.
  32. jwvanderbeck

    jwvanderbeck

    Joined:
    Dec 4, 2014
    Posts:
    825
    It took me all of about 15 minutes to write my own proper PushButton object, so i'm just going to use that.
     
  33. Rodolfo-Rubens

    Rodolfo-Rubens

    Joined:
    Nov 17, 2012
    Posts:
    1,197
    Split "Selected" from "Highlighted" is gonna be one more of those features that they never add, I guess...

    I hope not.
     
    Last edited: Jan 17, 2019
    JoeStrout likes this.
  34. superschure

    superschure

    Joined:
    Mar 31, 2017
    Posts:
    3
    I've come across this using Unity 5.6.1f1 Personal (OSX) and it's been nothing but an annoyance since in my case at least it's been a problem of fashion rather than function. I've come across something that has solved it in my case without using script. I'm programming my menus with the intent to use keyboard or controller input solely with no mouse option so whether or not this will solve your mouse problems is beyond me.

    Whether it be an OnClick or an EventTrigger (I use EventTrigger to control my Cancel button in menus), whichever button is performing your desired action add the same button as the OnClick Object then have the Animator call an Update(float) of zero. (Type "0"). My buttons use animations so I don't know if this will work with the other types like tinting, etc. To be safe I would add that to every button just to cover all bases but that's literally it and it works.

    Make sure that for your Normal animation that all the parameters are set to exactly what that button should look like when it is Normal. So if your text is blue on Normal and red on Highlight make sure that the Normal animation has the text as blue. Any animations that occur when your button is Highlighted need to be the opposite in the Normal animation; Normal needs to look like it is being animated as Normal rather than leaving the Normal state untouched.

    So in my example I have a Settings button, within that button's OnClick or EventTrigger area I add another OnClick Object, drag the exact same button from the Hierarchy into the field and go select Animator -> Update (float) with the number 0 and that's that.

    HighlightFix.png

    If this somehow breaks or goes screwy I'll update this post.
     
    bmenyhart likes this.
  35. Checko

    Checko

    Joined:
    Oct 23, 2013
    Posts:
    17
    Has anyone set up a custom controller to fix this? Is that even possible?
     
  36. TJHeuvel-net

    TJHeuvel-net

    Joined:
    Jul 31, 2012
    Posts:
    838
    I've opened a Pull Request about this: https://bitbucket.org/Unity-Technol...0/selectable-no-longer-selects-itself-on/diff

    It can be fixed in your own project by not using the default StandaloneInputModule but a custom one, that clears selection after sending an OnPointerDown. This is an example.

    How anyone can think that this is good behaviour is beyond me... This whole `Navigation` property is confusing, and 50% of the InputModules are deprecated. Clearly this is old design.

    At the very least have a different UI state for Highlighted and Selected.
     
    rakkarage, x4000 and JoeStrout like this.
  37. x4000

    x4000

    Joined:
    Mar 17, 2010
    Posts:
    353
    Well, that was a quick fix on my end. Plopping out the other one and in that one did the trick. Thanks!
     
  38. TJHeuvel-net

    TJHeuvel-net

    Joined:
    Jul 31, 2012
    Posts:
    838
    That is why i like this approach more than setting the Navigation property in each and every UI element. Eventhough you could do a GetComponentsInChildren to do it automatically too, it still feels super hacky.

    The only downside is that you'd have to be cautious when Unity updates their UI system. The input module might be updated too, and you'd have to re-apply the fix. One benefit is that the project hasnt been updated for months on Bitbucket.
     
    Last edited: Sep 20, 2017
  39. zorkwarrior

    zorkwarrior

    Joined:
    Apr 9, 2017
    Posts:
    1
    I've been hung up on this.
    I've tried the
    Code (CSharp):
    1. button.enabled = false;
    2. button.enabled = true;
    ... by GreatDane but it seems like a bit of a workaround with a bunch of extra code on all my methods.
    So I tried this instead and it seems to work. Mind you, I barely know what I'm doing so there may be unwanted side effects, but so far so good.

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3. using UnityEngine.EventSystems;
    4.  
    5. public class NewButton : Button {
    6.  
    7.  
    8.     public override void OnSelect (BaseEventData eventData)
    9.     {
    10.         print (this.gameObject.name + " selected!");
    11.  
    12.         InstantClearState();
    13.     }
    14. }
    The button that was pressed is no longer highlighted, but the method that onClick calls works.
     
  40. Killbert

    Killbert

    Joined:
    Mar 20, 2014
    Posts:
    3
    I agree that this is a massive issue that needs to be resolved.

    For those, who like me came here to find a solution: I have one that is more design-related than programmatic, thought I'd share it here in case it helps someone;

    I use a standard UI button based on an image and with color tint transitions.
    Normal color is set to be the same as Highlighted color.
    Using the event system, I added pointer exit and pointer enter events.
    In pointer enter, I enable another image inside my button gameobject.
    In pointer exit I disable the same image;
    In my case that extra image is set as a background, but it can be anything from an outline image to a different color image of the original button etc.

    This solves two problems visually for my users:

    1. visually, the button changes in appearance on pointer enter and pointer exit (mouse over);
    2. as there is no visual distinction between the regular button script normal state and the highlighted state, the user doesn't notice the 'Bug' or 'Feature' (lol) described in this topic.

    Also, it is quite easy to fix and requires no extra coding. Just a few clicks in the inspector. Also, if your qame requires a button to look different when it is not allowed to be clicked (i.e. out of bullets, cash or energy), this can still be accomplished in script via button.interactable = true / false;

    This still sucks a solution, but at the very least your users won't notice the bug (yes a bug!).
     
  41. jmiguelhdez

    jmiguelhdez

    Joined:
    Jan 2, 2017
    Posts:
    1
  42. Jribs

    Jribs

    Joined:
    Jun 10, 2014
    Posts:
    154
    Hey I was plagued by this issue and was starting to get pretty furious. It messed me up because eventually if you swapped between menus enough you could get all buttons highlighted at the same time making it impossible to know what you were selecting.

    I was using animation transitions. My solution was very simple. I noticed the animations were being reset to normal properly, but the issue was my "Normal" animation didn't actually alter anything. So I just added in the normal values for the variables that were changed by the other animations so that the animation actually changed some values of the button and it worked!

    Hope this helps others.
     
  43. Unity-Gripkiste

    Unity-Gripkiste

    Joined:
    Jul 13, 2016
    Posts:
    3
    Hey everyone.

    We had a similar problem with our adventure game. Or at least I hope it's the same problem. Could be my english.

    Anyhow, here's a simple solution that worked for our simple situation: Add an Event trigger - "on trigger exit", drag the button on it, set it to Button -> Button.OnDeselect.
     
    cloud_canvas and Riphtix like this.
  44. SimRuJ

    SimRuJ

    Joined:
    Apr 7, 2016
    Posts:
    247
    Unity 2017.3.1f1 - same problem here.

    If you don't need controller support, setting navigation to "None" is fine UNLESS you instantiate buttons (use a prefab) and set up an "onClick" ("myButton.onClick.AddListener(ClickMethod)") for them at runtime because then "EventSystem.current.currentSelectedGameObject.GetComponent()" just throws an exception!

    In this case bilalseh's solution (click) works perfectly: Just add

    Code (CSharp):
    1. EventSystem.current.SetSelectedGameObject(null);
    directly AFTER getting the currently selected button from the event system. Since it's in an "onClick" method, you don't even have to use "Update()" and also also don't need "Input.GetMouseButtonUp(0)";

    Unfortunately there's a big BUT: No matter what the navigation is set to, as soon as you use a touchscreen, the buttons don't reset properly, even if you reset the EventSystem by hand. :/ Still trying to get that fixed, so if anyone has a suggestion for that I would be grateful!
     
    ModLunar and JoeStrout like this.
  45. TooManySugar

    TooManySugar

    Joined:
    Aug 2, 2015
    Posts:
    864
    Last edited: Nov 2, 2018
  46. TooManySugar

    TooManySugar

    Joined:
    Aug 2, 2015
    Posts:
    864
    modify theese scripts to add/remove an specific script to all selectables.

    this last post wanted to post on the thread I linked above, I leave it here tho still usefull
     

    Attached Files:

    Last edited: Nov 1, 2018
  47. ModLunar

    ModLunar

    Joined:
    Oct 16, 2016
    Posts:
    374
    Hahaha all this frustration.. I had a good laugh reading this thread this morning XD. Good news though!! I found out they're adding a new state, "Selected", alongside Normal, Highlighted, Pressed, and Disabled in Unity 2019.1!

    I just upgraded to Unity 2019.1.0a13, which has the new "Selected" state, so I'm not sure how it works exactly yet. I was using 2019.1.0a8 and it wasn't in that version yet, so anyway -- good to know a solution is on it's way! :D
     
  48. yaodening

    yaodening

    Joined:
    Jul 31, 2015
    Posts:
    2
    :DWon:Dder:Dful:D!
     
    ModLunar likes this.
  49. Malkyne

    Malkyne

    Joined:
    Nov 18, 2009
    Posts:
    39
    If this is true, ModLunar, I may have a celebratory beer!
     
    ModLunar likes this.
  50. Rodolfo-Rubens

    Rodolfo-Rubens

    Joined:
    Nov 17, 2012
    Posts:
    1,197
    Ah, cool, after 2 years I can finally edit my post... Better late than never.
     
    ModLunar and Malkyne like this.