Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Clicking off button causes selected button to become deselected

Discussion in 'UGUI & TextMesh Pro' started by NeilB133, Oct 12, 2022.

  1. NeilB133

    NeilB133

    Joined:
    May 30, 2022
    Posts:
    214
    The video below demonstrates an issue I'm having. I've set it up in a way so that when either the arrow keys or WASD are moved around it selects a button (the buttons in this case are weapons from your full inventory) or you can select the weapon by simply clicking it. This in turn, sets a boolean to true in the script, as you'll see in the video (the bool being called weaponChosen). However, if I click off any of the buttons, anywhere (even something that's not a button, just an image UI for example) it deselects the last button that was selected. I wondered if there was a way to have it not deselect anything unless you've clicked another button (aka a weapon)



    Thanks guys :)
     
    Last edited: Oct 13, 2022
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    39,053
    The way I do this is to watch what is selected and if there ever isn't one of the things that I decide MUST always be selected, I reselect the last one that I had observed selected in that list, eg, in the previous frame.

    You can select stuff via the EventSystem: and I believe it's this call:

    https://docs.unity3d.com/2019.1/Doc...ystems.EventSystem.SetSelectedGameObject.html

    Note: it is an instance method, not a static... use the
    .current
    shortcut
     
  3. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,589
    Please don't use the 2D forum for UI support. There's a dedicated UI forum here where I'll move your post.

    Thanks.
     
  4. NeilB133

    NeilB133

    Joined:
    May 30, 2022
    Posts:
    214
    Interesting, I'll have a look at this tonight, so yeah, I guess at that point I know that at least 1 of the 4 of the weapons MUST be selected.

    so essentially if EventSystem.current.currentSelectedGameObject != to any of the 4, select the previous selected. Previously selected could be stored in a variable. But yeah will look at tonight, thanks for the idea :)
     
    Last edited: Oct 13, 2022
  5. NeilB133

    NeilB133

    Joined:
    May 30, 2022
    Posts:
    214
    Ah sorry about this Melv! Totally slipped my mind, thank you for moving :)
     
    MelvMay likes this.
  6. NeilB133

    NeilB133

    Joined:
    May 30, 2022
    Posts:
    214


    Got it working :) So now if you click anywhere else it doesn't deselect it. Thank you again for the suggestion @Kurt-Dekker .

    Here is my code if you're interested. I had the GameObject array turned into a List, which I could then use the Compare method on. So I checked to see if the selected GameObject was in the List of weapon selections, if not, then it selected the previously selected. I also had to do the same for the two buttons on the page - the Cancel and the Swap buttons, if I didn't, it wouldn't let me select them and execute their functions.

    Code (CSharp):
    1. public class WeaponSwapButtonLogic : MonoBehaviour
    2. {
    3.     public GameObject firstWeaponSelected;
    4.     public List<GameObject> weaponButtons;
    5.     public List<GameObject> cancelAndSwapButtons;
    6.     public GameObject lastSelectedButton;
    7.    
    8.     void Start() {
    9.  
    10.         emptyAndSetSelectedGameObject(firstWeaponSelected);
    11.     }
    12.    
    13.     void Update() {
    14.  
    15.         GameObject selectedGameObject = EventSystem.current.currentSelectedGameObject;
    16.  
    17.         foreach (GameObject weaponButton in weaponButtons) {
    18.  
    19.             SwapButtonLogic swapButtonLogic = weaponButton.GetComponent<SwapButtonLogic>();
    20.  
    21.             if (weaponButton == selectedGameObject) {
    22.                 swapButtonLogic.weaponChosen = true;
    23.                 lastSelectedButton = weaponButton;
    24.             }
    25.             else {
    26.                 swapButtonLogic.weaponChosen = false;
    27.             }
    28.  
    29.             if ( ! weaponButtons.Contains(selectedGameObject) || ! cancelAndSwapButtons.Contains(selectedGameObject)) {
    30.  
    31.                emptyAndSetSelectedGameObject(lastSelectedButton);
    32.             }
    33.         }
    34.     }
    35.  
    36.     void emptyAndSetSelectedGameObject(GameObject gameObjectToSelect) {
    37.  
    38.         EventSystem.current.SetSelectedGameObject(null);
    39.         EventSystem.current.SetSelectedGameObject(gameObjectToSelect);
    40.     }
    41. }
     
    Kurt-Dekker likes this.
  7. sullyjhford

    sullyjhford

    Joined:
    Mar 25, 2023
    Posts:
    1
    Hey there, I've been looking for a solution to this problem for a while now, the above does work wonders, but I was trying to avoid this mostly because I didn't want the UI to really have anything in its Update function.

    In my case there are wrapping *Screen components (MainMenuScreen, AchievementsScreen etc.) which can have multiple buttons inside them, so all it is doing in the Update function is looping through the buttons registered to that screen and checking whether at least one is selected and selecting the last selected or default button if there aren't any.

    This doesn't seem to have any performance impact really, but is my apprehension justified for this? I'm fairly new to Unity so don't fully have a grasp of what's expensive and what's not yet, so just putting the question out there to anyone more familiar with it.