How to get controller/keyboard navigation/focus working with UI Toolkit List View?

I’m having trouble figuring out the right way to use ListView in UI Toolkit to make basic scrollable menus.

  1. Simple menus
    I have a list of items of arbitrary length which represent a game menu, like this:


    This is implemented as a ListView where the item type is a custom visual element which contains a button. The buttons are clickable and work, but I need to support controller and keyboard. Currently pressing WASD/arrow keys/controller direction does nothing. In my previous implementation which did not use a list, but used the same type of elements as simple children, focus was correctly passed between them.
    The reason I want to use a list here is because I need this menu to potentially contain a very large number of items with a scroll bar. I want that to have controller support, such that moving to the bottom of the scroll viewport scrolls the list to the next item, and wraps around to select the top item when i get to the bottom.

  2. Master-Detail menu
    I have a similar situation with a list where I want to use the selection of a list that is controlled with both mouse and keyboard and controller. Like this:


    This is set up with a ListView that has SelectionType.Single. Clicking an item changes the selection and I update my detail view via listView.selectionChanged. This works, but again has no keyboard or controller support. Here, I want the same behavior as above except instead of the directional buttons/keyboard/controller changing the focus or whatever, it needs to change the selection.

Is there a way to accomplish this in the latest Unity 6 release?

Do you have an active event system component/game object with an associated input module?

Yes. As I mentioned, keyboard navigation does work in my UI if I place buttons in a visual element, but it does not work in a list view. And I don’t even understand where to begin with controlling the selection of the list view.

ListView navigation has always worked for me out of the box, though my current project is sitting at 2023.3.20, rather than on the latest Unity 6 version.

If it isn’t working then I’d peg this as a bug potentially.

OK, I figured out what was causing the events not to get picked up. It seems that keyboard and controller events affect the selection of the list view (in USS as :checked, which is not documented). So the list view must be in single or multi selection mode to accept that input.

My remaining struggle is how to handle mouse input, because clicking once changes the selection and fires selectionChanged, and double clicking fires itemsChosen.

However, the double click behavior is weird for this type of list, I want it to be a single click, like a button. I can almost use selectionChanged for this, if I check whether the current input device is a mouse and fire my action on selection changed if it was activated with the mouse. However, this fails when the item is already selected. I guess the best option is to clear the selection whenever the input device changes to the mouse. Or is there a more straightforward way of doing all of this?

You can just hook into the UI Toolkit callbacks yourself.

In makeItem or perhaps bindItem register a callback for a ClickEvent on the list item visual element, and unregister it in unbindItem or destroyItem.

Or define a custom visual element and encompass it all in there. Then it’s just a matter of having a delegate to hook into, and something to fire off said delegate.

1 Like