Search Unity

Bug DropDownSelect nonfunctional; strange repeated Focus events

Discussion in 'UI Toolkit' started by gtaogle, Dec 3, 2022.

  1. gtaogle

    gtaogle

    Joined:
    Jan 6, 2022
    Posts:
    18
    Hello, hoping to find some assistance here with what might be a configuration issue.

    When I implement a UI Toolkit Drop Down Select, it doesn't pop up the list of options. I was butting my head up against a lot of possible solutions to this, but I'm rather certain these issues didn't describe what I'm dealing with.

    The basic misbehavior can be described as "the highlight color flickers and the dropdown list appears and disappears rapidly."

    I attached some event listeners for various events to the dropdown, and the FocusEvent showed that after clicking the dropdown, it was repeatedly fired instead of being fired once, which suggests something odd going on with the project in regards to the event system (or something of this sort.)

    (The suggestion to do this came from this thread: https://forum.unity.com/threads/dropdownfield-options-popup-missing.1344980/#post-8613975 as an idea of assuming that Unity is bugged right now and the field won't open on its own.)

    Since the field's option list does appear to normally open on focus, the fact that the focus event is repeating as if the object is losing and regaining focus repeatedly does explain the option list not appearing (or blinking in and out and being unusable.)

    In order to stop this behavior I have to click outside the dropdownfield's label/dropdown button area, which among the issues I'm having is the most logical thing.

    To confirm there's some incorrect behavior going on I attached a blur event as well


    Code (CSharp):
    1.        ...
    2.         pickGraph.RegisterCallback<FocusEvent>(onFocus);
    3.         pickGraph.RegisterCallback<BlurEvent>(onBlur);
    4.  
    5.     }
    6.  
    7.     public void onFocus(FocusEvent evt) {
    8.         Debug.Log("focused");
    9.         var elem = uiDoc.rootVisualElement.focusController.focusedElement;
    10.         if (elem == null)
    11.         {
    12.             return;
    13.         }
    14.         if (elem is DropdownField)
    15.         {
    16.             var ev = KeyDownEvent.GetPooled(default(char), KeyCode.KeypadEnter, EventModifiers.None);
    17.             elem.SendEvent(ev);
    18.         }
    19.      
    20.     }
    21.  
    22.     public void onBlur(BlurEvent evt) {
    23.         Debug.Log("blurred");
    24.     }
    And the result confirms this (there are hundreds of these in the Editor log)

    focused​
    UnityEngine.Debug:Log (object)
    StatusUI:eek:nFocus (UnityEngine.UIElements.FocusEvent) (at Assets/Scripts/StatusGraphs/StatusUI.cs:55)
    UnityEngine.EventSystems.EventSystem:Update () (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/EventSystem.cs:501)

    blurred
    UnityEngine.Debug:Log (object)
    StatusUI:eek:nBlur (UnityEngine.UIElements.BlurEvent) (at Assets/Scripts/StatusGraphs/StatusUI.cs:70)
    UnityEngine.UIElements.UIElementsRuntimeUtilityNative:UpdateRuntimePanels ()​

    focused
    UnityEngine.Debug:Log (object)
    StatusUI:eek:nFocus (UnityEngine.UIElements.FocusEvent) (at Assets/Scripts/StatusGraphs/StatusUI.cs:55)
    UnityEngine.EventSystems.EventSystem:Update () (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/EventSystem.cs:501)​

    blurred
    UnityEngine.Debug:Log (object)
    StatusUI:eek:nBlur (UnityEngine.UIElements.BlurEvent) (at Assets/Scripts/StatusGraphs/StatusUI.cs:70)
    UnityEngine.UIElements.UIElementsRuntimeUtilityNative:UpdateRuntimePanels ()​

    Any idea what might cause such behavior? There is an EventSystem in the Scene, which has an active Standalone Input Module. One of the properties of it is "Input Actions per Second", which if I reduce to 1, causes the blinking to slow down a lot. If I disable it however, the select does not seem to receive any events, which I guess makes sense *if* indeed the Standalone Input Module is what the event system is using to catch and propagate input events.

    Any help here would be appreciated, I was not expecting to need to learn the guts of the Unity input handling system just to get my dropdown to work.

    EDIT: I created a new project and created the minimal working UI Toolkit UI with just a select, populated the select with some options like this


    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.UIElements;
    5.  
    6. public class UIBehavior : MonoBehaviour
    7. {
    8.     public UIDocument uidoc;
    9.  
    10.     // Start is called before the first frame update
    11.     void Start()
    12.     {
    13.         DropdownField select = uidoc.rootVisualElement.Q<DropdownField>("SampleDropdown");
    14.         select.choices.Clear();
    15.         select.choices = new List<string>() { "Choice A", "Choice B" };
    16.         select.SetValueWithoutNotify("Choice A");
    17.     }
    18.  
    19.     // Update is called once per frame
    20.     void Update()
    21.     {
    22.      
    23.     }
    24. }
    And on run, I get the same bizarre behavior. The sample scene has just a camera and the UIDocument.

    EDIT: with further testing, the issue is slightly different, I don't get the repeated blinking but the select simply doesn't open. Version is 2021.3.15f1 which is the recommended version right now.
     
    Last edited: Dec 3, 2022
  2. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,282
  3. gtaogle

    gtaogle

    Joined:
    Jan 6, 2022
    Posts:
    18
    I can do that tomorrow, I also tried this in 2022.1.23f1 and I get some similar weird behavior with this particular component. I want to figure out what bug I'm reporting first :D
     
    karl_jones likes this.
  4. dlorre

    dlorre

    Joined:
    Apr 12, 2020
    Posts:
    699
    Most of my issues with UI Toolkit come from the focus/navigation part, one way or another. That said, I don't think that you should use OnFocus() but rather react to a keypress to open the DropDown. Normally the dropdown should work when you click on it with the mouse, but won't react to keypresses.

    Since I use the new input system, I implement an InputAction and the function goes like this:

    Code (csharp):
    1.  
    2.         private void actionSubmit(InputAction.CallbackContext context)
    3.         {
    4.             var elem = root.focusController.focusedElement;
    5.             if (elem == null)
    6.             {
    7.                 return;
    8.             }
    9.             if (elem is DropdownField)
    10.             {
    11.                 var ev = KeyDownEvent.GetPooled(default(char), KeyCode.KeypadEnter, EventModifiers.None);
    12.                 elem.SendEvent(ev);
    13.             }
    14.     }
    15.  
    If it does not react to the mouse click then it's another issue I am unaware of.
     
  5. gtaogle

    gtaogle

    Joined:
    Jan 6, 2022
    Posts:
    18
    I've been following tutorials for UI Toolkit and haven't seen anything about a "new input system" -- but it does explain what one of the interlocutors in the other thread meant by 'InputAction'! It could simply be an incompatibility with existing UI and the old input system that's only affecting the dropdowns (I had problems with the old dropdowns, so I switched to the new system to see if I could get a working dropdown.)

    Where can we find out about the new input system?
     
  6. dlorre

    dlorre

    Joined:
    Apr 12, 2020
    Posts:
    699
    Well you don't have to use the new input system to use UI Toolkit, just that if you don't then the method for grabbing keypresses is different. samyam's videos on YT are a good start to use the new input system.



    Personally I use it because I don't want to put too much stuff in Update(), so having an event telling me that a key I'm expecting for was pressed is more of my likings.
     
  7. gtaogle

    gtaogle

    Joined:
    Jan 6, 2022
    Posts:
    18
    Ah, seems I can't view that video. What is the new system called?
     
  8. dlorre

    dlorre

    Joined:
    Apr 12, 2020
    Posts:
    699
  9. gtaogle

    gtaogle

    Joined:
    Jan 6, 2022
    Posts:
    18
    Thanks, I may have a look at it sometime soon, if I decide to continue game development after this.

    The ticket has been submitted for this issue, I hope it is helpful to someone.
     
  10. dlorre

    dlorre

    Joined:
    Apr 12, 2020
    Posts:
    699
    You don't have to use the new input system you can do it like so:

    Code (csharp):
    1.  
    2. void Update()
    3. {
    4.    if (Input.GetKeyDown(KeyCode.Space))
    5.    {
    6.         // code to handle the dropdown field here
    7.    }
    8. }
    9.  
     
  11. gtaogle

    gtaogle

    Joined:
    Jan 6, 2022
    Posts:
    18
    Yes, if you wanted to open the dropdown with a space press, that may work! But I don't, I want to open it with a mouse click.
     
  12. dlorre

    dlorre

    Joined:
    Apr 12, 2020
    Posts:
    699
    It works for me with mouse click. Try with a new project maybe?
     
  13. gtaogle

    gtaogle

    Joined:
    Jan 6, 2022
    Posts:
    18
    Nope, made several different new projects (Sample 2D) and I get the same behavior. Additionally, the ListView double-registers clicks sometimes, with the second click not being on any item, which results in the item getting deselected even without the event system added. Seems like the UI stuff is mostly broken in 2022.1.23f1

    I made the attempt to completely isolate the control and it only in a game and it still misbehaves. I just need a working UI, if I wanted to build it myself I could use LWJGL again.

    It makes me wonder if Unity is somehow partially incompatible with some versions of Windows 10.

    EDIT: I spent a few hours getting the new Input System to work.

    1. Changing to the new input system caused the listview to simply work as it was supposed to (no repeated extra clicks;)
    2. It did not cause the dropdownfield to work. However; creating a mouse click event and following the above logic does allow me open the dropdown with a mouse click, but not in the proper way. To get the dropdown to extend, you have to click on it twice (dropdowns should extend on the first click on the dropdown itself - and not the label unless specified) which is kind of janky.

    Note that I did not use the Player Input but just the C# class which has configuration generated from the asset. I'm not sure why I have to click on it twice to get it to extend, but I do grasp that because we're not specifying what _part_ of the dropdown visual element we click on a click anywhere in its real estate (which include the label) passes our pretty scary "hook run on every click when this script is loaded on an object." I think I would prefer to use the built in events in UI Toolkit rather than this, since UI Toolkit has its own raytracer.

    FINAL EDIT: I switched it to a space press, but that means you have to click the dropdown and then press space. Egads!
     
    Last edited: Dec 5, 2022
  14. dlorre

    dlorre

    Joined:
    Apr 12, 2020
    Posts:
    699
    Okay, good thing that you have made progress. I've had a lot of issues with the input myself. However what you can do is download Dragon Crashers and check how it works because it has some dropdown fields.