Search Unity

Make button lose focus on roll out

Discussion in 'UGUI & TextMesh Pro' started by LeRan, Aug 1, 2016.

  1. LeRan

    LeRan

    Joined:
    Nov 24, 2015
    Posts:
    118
    Hi, there's this little something I'm trying to do but can't... I'll explain by steps:
    1) hover over a button -> it gets highlighted (OK)
    2) press (but not release) the button -> it takes the "pressed" sprite but does not trigger anything since the event in on release (OK)
    3) roll out -> the button should returns from the "pressed" sprite to the "neutral" sprite (not OK! it takes the highlighted sprite)

    I would like the button to lose focus on roll out, and not to stay highlighted.

    The difference is not only cosmetic : once the mouse is released, the button behaves as if the mouse was still on it and triggers the "pointer up" event. Or, to put it otherwise, once the mouse is pressed over the button, the fact to roll out of the button without releasing the mouse should be able to cancel that order.

    I could not find an answer on the internet, maybe I'm missing something basic?
     
  2. eses

    eses

    Joined:
    Feb 26, 2013
    Posts:
    2,637
    @LeRan

    I don't think so.

    IIRC, it behaves just like that.

    Buttons are also navigable by keys, so I think it's in that sense logical that clicking on button, then moving mouse outside and releasing mouse button, it will keep button highlighted, as this would be still the last selected UI item?

    And for PointerUp, I think it worked just like that, it's been a while since I had to deal with it.
     
  3. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,187
    LeRan likes this.
  4. eses

    eses

    Joined:
    Feb 26, 2013
    Posts:
    2,637
    @Brathnann has already most likely solved your issue, but my solution was something like this:

    Code (csharp):
    1.  
    2. public class DeselectOnPointerUp : MonoBehaviour, IPointerUpHandler
    3. {
    4.   Button button;
    5.  
    6.   void Awake ()
    7.   {
    8.   button = this.GetComponent<Button>();
    9.   }
    10.  
    11.   public void OnPointerUp(PointerEventData eventData)
    12.   {
    13.   EventSystem.current.SetSelectedGameObject(null);
    14.   }
    15. }
    16.  
     
    Woof359 and LeRan like this.
  5. LeRan

    LeRan

    Joined:
    Nov 24, 2015
    Posts:
    118
    Thanks for your answers. I've been trying that solution (with OnPointerExit since that's what I'm trying to do) but the behaviour remains the same as before: in fact, the selected game object (EventSystem.current.currentSelectedGameObject) remains "null" the whole time.

    But, despite the "selected game object" being null, the button still acts as clicked (on pointer up) after roll out just as before.

    I'm still trying to figure out why...
     
  6. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,187
    LeRan and eses like this.
  7. LeRan

    LeRan

    Joined:
    Nov 24, 2015
    Posts:
    118
    @Brathnann Thanks! I'm making some progress here: with OnPointerExit and EventSystem.current.SetSelectedGameObject(null) I'm now able to return the button's sprite to the neutral state after "clicked but not realeased roll out" (I wish there existed a word for that).

    Note for the record: this is only possible if the navigation parameter of said nutton is not set to "none".

    But, as you mentionned: I still can't get rid of the "clicked" state yet: whereas the button is still back to it's neutral appearance after roll out, it still activates once the mouse button is released, just as a classic OnRelease event trigger.

    Still searching...

    P.S. The InstantClearState protected function looks tempting, but I'm not sure since I can't managed to invoke it, let alone make it work...
     
    Last edited: Aug 2, 2016
  8. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,187
    It says it's used when disabling. What happens if you disable and enable the button script?
     
    LeRan likes this.
  9. LeRan

    LeRan

    Joined:
    Nov 24, 2015
    Posts:
    118
    Allright, I officially suck, but now I know that so I can design a solution on that basis! Since I like my actions to happen on release and not on click, my button was also equiped with an Event Trigger script. That's that event trigger that should be disabled, not the button itself!

    Anyway, even knowing that, it remains a bit tricky: the "pointer down" state of the event trigger will not disappear so easily. So, what must be done is, as far as I know :
    1) manually unselect the button to make it lose its highlighted status after rollout (note : SetSelectedGameObject(null) works but disabling and immediately re-enabling the button does the trick too).
    2) manually disable the event trigger to prevent it from firing on button up.
    3) manually re-enable the event trigger on pointer enter so that the control still works as intended.

    It's the closest I could come to the desired effect, so I think that'll be good enough for now.

    Anyway, thanks for your advice and for taking the time to help a moron like me :/
    Here is the code just in case.

    Code (CSharp):
    1. public class Deselectionne_Bouton : MonoBehaviour, IPointerExitHandler, IPointerEnterHandler {
    2.  
    3.     Button leBouton;
    4.     EventTrigger leTrigger;
    5.        
    6.     void Awake ()
    7.     {
    8.         leBouton = this.GetComponent<Button>();
    9.         leTrigger = this.GetComponent<EventTrigger> ();
    10.     }
    11.  
    12.     public void OnPointerExit(PointerEventData eventData)
    13.     {
    14.         leTrigger.enabled=false;
    15.         EventSystem.current.SetSelectedGameObject(null);
    16.     }
    17.  
    18.     public void OnPointerEnter(PointerEventData eventData)
    19.     {
    20.         leTrigger.enabled=true;
    21.     }
    22. }
     
  10. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,187
    Nice. Glad you got it working the way you want (or at least close to it!).