Search Unity

Navigation between menus with a controller?

Discussion in 'UGUI & TextMesh Pro' started by yosefstudios, Jan 14, 2021.

  1. yosefstudios

    yosefstudios

    Joined:
    May 8, 2015
    Posts:
    129
    The goal: make an interactable main menu that can be navigated with a gamepad/controller (Xbox One/Ps4, for example).
    The problem: well...

    As I been searching trough the internet, I've stumbled across multiple post here, Unity answers, YouTube, and other websites that talk about different solutions to make a menu system with the new UI system compatible with controllers, however, most of them looked like more as temporal/hacky solutions. It is supposed that the new UI system works with keyboard as well with controllers, isn't it? When you connect a controller and Unity detects it, the UI should be working...but it doesn't. So, according to my research, you need to set up a First Selected game object in the Event System in order to make it work. Now, connect the controller, and, for example, the Start Game button is now highlighted, and of course, you can move between interactable options under the same game object.

    However, if you want to enter to a new window (from the main menu to the settings menu, for example), the last selected object remains selected (the settings button that leads to the settings menu is still being highlighted and according to the Event System, still selected).

    There's this video that covers that issue:


    The solution presented is basically this 2 lines of code:


    //Clear
    EventSystem.current.SetSelectedGameObject(null);
    //Reassign
    EventSystem.current.SetSelectedGameObject(gameobject);


    So, in the video, the user uses those 2 lines every time he enters to the pause menu and when he changes from the main view to the settings view. Apparently, the code is supposed to remove the First Selected object and replace it with a new one. The user himself says that he doesn't understand why we need to do that. There are some posts here that says that may be a bug, like this one([Button] Keyboard and Mouse Highlighting - Unity Forum). There was another older one, which I couldn't find again, but that post should be where the 2 lines of code trick came from (again, it talked about how it may be a bug, but that person was told that "it was by design").

    Now, back to my example, if I want to move from the main menu to the settings menu, the first selected object remains as the options button, instead of changing to the first selectable option on the settings view. So, to solve that, you use the trick mentioned above. Unfortunately, not even that worked for me. For some reason, the last selected object remains selected, therefore, I can't navigate with the controller again, unless I click with the mouse somewhere.

    So, I'm using a method that is getting called once the user press certain button, and it goes like this:

    Code (CSharp):
    1. public void SetSelectedGameObjectToSettings()
    2.     {
    3.         //Clear
    4.         eventSys.SetSelectedGameObject(null);
    5.         //Reassign
    6.         eventSys.SetSelectedGameObject(defaultOptionsSelection);
    7.     }
    The defaultOptionsSelection object is set on the inspector. As I stated before, for some reason it's not working.

    I had that issue on Unity 5.6 too, but somehow it just magically worked at some point (don't know what I did to make it work, honestly). Now, I'm working on Unity 2018.4, and it seems it doesn't work there...
     
  2. yosefstudios

    yosefstudios

    Joined:
    May 8, 2015
    Posts:
    129
    Forgot to mention: the console gives me the NullReference error when I try to execute the code above, and well...the error comes from the line that specifically set the SelectedGameObject as null.
     
  3. Thomascain7i

    Thomascain7i

    Joined:
    Oct 5, 2022
    Posts:
    1
    Did you ever find the answer?
     
  4. yosefstudios

    yosefstudios

    Joined:
    May 8, 2015
    Posts:
    129
    Uhhh kinda? I think I did. My solution had something to do with coroutines and timing. Right now I don't have access to that project, but I believe it was something like:

    Code (CSharp):
    1. // Inside a coroutine
    2.  
    3. 1. Remove the First Selected object from the event system
    4. 2. Reset the event system
    5. 3. Wait a frame
    6. 4. Actually call the method that you wanted to trigger (activating a new window, for example)
    7.  
    8. // On another script
    9.  
    10. 1. Set the new first selected object
    11. // Done?