Search Unity

[Button] Keyboard and Mouse Highlighting

Discussion in 'UGUI & TextMesh Pro' started by ReynV, Jan 28, 2015.

  1. ReynV

    ReynV

    Joined:
    Sep 24, 2014
    Posts:
    50
    Hi.
    I'm working on a code generated menu that should work with both keyboard and mouse inputs.

    1. I call EventSystem.current.SetSelectedGameObject(firstMenuOption) to get the first button highlighted
    2. If the user decides to use the mouse instead of the keyboard
    3. Then both the firstMenuOption and the button under the mouse cursor is in the highlighted state

    I assume this is expected behaviour? Should I run through all my buttons and deselect them if the mouse is over a button ? Or is there some other built in way of handling button highlighting with both the keyboard and mouse ?

    An example of this can be seen from example 5 onwards: http://reyn.vlietstra.co.za/?page_id=248

    Thanks!
     
    Last edited: Jan 28, 2015
  2. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,689
    ??
    By having both the StandaloneInputModule and the TouchInputModule attached to the EventSystem in your scene (the default),you should have both mouse / keyboard and touch input for your UI, without doing anything else.

    Or is there something I'm missing in your query?
     
  3. ReynV

    ReynV

    Joined:
    Sep 24, 2014
    Posts:
    50
    Hi Simon.
    Both the mouse and keyboard input is working.

    I would like only one of my menu buttons to be highlighted at any one time.

    At the moment the button that is explicitly selected with SetSelectedGameObject is always highlighted, in addition to whatever button the mouse cursor is over.

    Could it be that both the input module components are separately keeping their own selected item causing two buttons to be highlighted in my UI ?

    Please check Example 5/6/7/8 in the supplied link.

    Thanks!
     
    Last edited: Jan 29, 2015
  4. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,689
    I'll check out your example tonight.

    The EventSystem is the central manager that maintains what is selected / clicked and which input system is being assessed.
    It could be this is an actual bug with the SetSelectedGameObject function where is causes the set object to remain set regardless of the next update.
     
  5. GuilhermeAbeL

    GuilhermeAbeL

    Joined:
    Mar 22, 2014
    Posts:
    1
    Hello!

    I'm having some kind of trouble with that too. I created a function that is triggered when your mouse cursor pass over a button:


    public void SetTheButtonMouseIsOver (GameObject currentButton)
    {
    EventSystem.current.SetSelectedGameObject(currentButton, null);
    }

    Now, when I'm using the keyboard and decide to use the mouse, I don't get 2 highlighted buttons anymore, only the one under the cursor.

    But...
    If a button is highlighted because of the cursor that is over it, when I decide to use the keyboard, even if I press any arrow and select another option, the button under the cursor is still highlighted. Tried to creat a boolean, but it didn't work:

    //MOUSE
    public float currentMouseX;
    public float currentMouseY;
    public bool usingKeyboard;

    void Update ()
    {
    if(GameObject.Find("Main Camera").GetComponent<LevelBehaviour>().pauseOn)
    {
    if(Input.GetAxis("Mouse X") != currentMouseX || Input.GetAxis("Mouse Y") != currentMouseY)
    {
    usingKeyboard = false;
    currentMouseX = Input.GetAxis("Mouse X");
    currentMouseY = Input.GetAxis("Mouse Y");
    }
    }
    }


    public void SetTheButtonMouseIsOver (GameObject currentButton)
    {
    if(!usingKeyboard)
    {
    EventSystem.current.SetSelectedGameObject(currentButton, null);
    }
    }

    //This one is called when I move using keyboard
    public void UpdateCurrentButton (GameObject currentButton)
    {
    usingKeyboard = true;
    }

    Already tried to make the canvas unblock the raycast and other stuff, but nothing worked...
    I was thinking about changing the animation state of the button under the cursor via script (could do this inside this last function, instead of just turning the bool on), but I don't know how to do that lol
     
  6. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,689
    It has been noted there is a bug with the highlighting code at the moment, it doesn't clear the highlighted state of the previous control sometimes.
    You can test this by adding two buttons, highlight one, click on it and then move the pointer over another. The result is two buttons in a highlighted state. UT are aware of the issue at the mo as far as I know.
     
    GuilhermeAbeL likes this.
  7. el_rolas

    el_rolas

    Joined:
    Aug 6, 2012
    Posts:
    15
    Same Issue Here, have you fixed?
     
  8. TripleBorisInc

    TripleBorisInc

    Joined:
    Nov 11, 2016
    Posts:
    2
    Bump. Have the same issue. Was this fixed?
     
  9. ReynV

    ReynV

    Joined:
    Sep 24, 2014
    Posts:
    50
    I still have the issue. Very disappointing.
     
  10. daterre

    daterre

    Joined:
    Jul 30, 2012
    Posts:
    41
    After some digging around in the Unity UI source on BitBucket I came up with the following solution. The problem seems to be that the Selectable component (on which Button is based) uses the "highlight" state for two different cases (selected and hovering) and doesn't clearly distinguish between the two. This causes a deselected object to remain highlighted because OnPointerExit hasn't been called. My solution is to automatically select the object on pointer enter (which might have repercussions but works for my needs) and automatically trigger the OnPointerExit behavior when deselected.

    Code (CSharp):
    1. using System;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using UnityEngine.EventSystems;
    6. using UnityEngine.UI;
    7.  
    8.  
    9. [RequireComponent(typeof(Selectable))]
    10. public class HighlightFix : MonoBehaviour, IPointerEnterHandler, IDeselectHandler
    11. {
    12.     public void OnPointerEnter(PointerEventData eventData)
    13.     {
    14.         if (!EventSystem.current.alreadySelecting)
    15.             EventSystem.current.SetSelectedGameObject(this.gameObject);
    16.     }
    17.  
    18.     public void OnDeselect(BaseEventData eventData)
    19.     {
    20.         this.GetComponent<Selectable>().OnPointerExit(null);
    21.     }
    22. }
    23.  
     
  11. jamie_unity

    jamie_unity

    Joined:
    Feb 3, 2017
    Posts:
    4
    Thanks - that works just fine for my purposes, too. I'm usuing Unity 5.6 and it seems to still be an issue.

    For anybody reading, the only thing the quoted post might not make clear is that this script should be attached to any buttons you want to properly reselect if/when the user switches from a keyboard to mouse input.
     
    WayneJP and Eater_Games like this.
  12. Hi_ImTemmy

    Hi_ImTemmy

    Joined:
    Jul 8, 2015
    Posts:
    174
    2022 checking in. I'm up against the "mouse cursor still highlighting buttons" problem. This script solved the issue, but, introduced a new problem which is a button with the script will remain highlighted when the mouse cursor leaves it.

    In this GIF the quit button doesn't have the script. The others do.
     
  13. aydin_khp

    aydin_khp

    Joined:
    May 15, 2020
    Posts:
    29
    I made a change to the script so that the selection gets lost (i.e. no active selected object) when the mouse cursor leaves. It works for me now but I am not sure about the edge case.

    Code (CSharp):
    1.     [RequireComponent(typeof(Selectable))]
    2.     public class HighlightFix : MonoBehaviour, IPointerEnterHandler, IDeselectHandler, IPointerExitHandler
    3.     {
    4.         public void OnPointerEnter(PointerEventData eventData)
    5.         {
    6.             if (!EventSystem.current.alreadySelecting)
    7.                 EventSystem.current.SetSelectedGameObject(this.gameObject);
    8.         }
    9.  
    10.         public void OnPointerExit(PointerEventData eventData)
    11.         {
    12.             if (EventSystem.current.currentSelectedGameObject == this.gameObject)
    13.                 if (!EventSystem.current.alreadySelecting)
    14.                     EventSystem.current.SetSelectedGameObject(null);
    15.         }
    16.  
    17.         public void OnDeselect(BaseEventData eventData)
    18.         {
    19.             this.GetComponent<Selectable>().OnPointerExit(null);
    20.         }
    21.     }
    22.