Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Best approach to "ClickOutsideEvent"

Discussion in 'UI Toolkit' started by poprev-3d, Mar 8, 2023.

  1. poprev-3d

    poprev-3d

    Joined:
    Apr 12, 2019
    Posts:
    69
    I'm developing a custom dropdown menu (from scratch) and need to close the dropdown part when the user clicks once outside of the menu. I'm seeking for a kind of event that is triggered when the user clicks outside of the element, this click can either occur on the UI panel or outside of it (in the game view for example).

    What would be the best approach to a kind of "ClickOutsideEvent" using the new UI toolkit ?

    I've tried different approach, but none are really convincing:
    • Using the GenericDropdownMenu base class. Downside of this is that i have little to no control on what's happening, and the position of the menu is kind of relative to the root of the panel, which i don't want. The size and position of GenericDropdownMenu is controlled via a rect element, which is kind of tricky, as it's kind of overriding the uss layout structure.
    • Using the original dropdown is not an option (I've got too many custom behaviors in my dropdown)
    • Using a loop that checks the first click outside of the element, but frankly, it's not really clean nor performant (as it's not event based)
    upload_2023-3-8_8-33-59.png

    Thanks !
     
    Last edited: Mar 8, 2023
    mariandev and andrewPrevu3d like this.
  2. noirb

    noirb

    Joined:
    Apr 10, 2014
    Posts:
    84
    Create an extra VisualElement with a transparent background which covers the whole screen and sits behind your dropdown in the hierarchy. If the user clicks on the invisible element, close the dropdown (and remove the invisible element).
     
    poprev-3d likes this.
  3. Homicide

    Homicide

    Joined:
    Oct 11, 2012
    Posts:
    637
    Noirb has provided one way of doing it, and it would work quite well, easily. The other thing you can do , is look into IPointer events.

    IPointerEnter, IPointerExit are very well served for this kind of thing and more. GL
     
  4. poprev-3d

    poprev-3d

    Joined:
    Apr 12, 2019
    Posts:
    69
    Thanks @noirb, that's the approach GenericDropdownMenu uses and that i replicated, it works well.
     
  5. tlskillman

    tlskillman

    Joined:
    Dec 12, 2015
    Posts:
    16
    Hey @poprev-3d, can you share your code. I'm wrestling with a similar, and but hopefully simpler, situation. I'm ok with most of the standard dropdown behavior, but just want the dropdown to close if the player clicks outside the dropdown. Thanks.
     
  6. poprev-3d

    poprev-3d

    Joined:
    Apr 12, 2019
    Posts:
    69
    @tlskillman I highly recommend you to use GenericDropdownMenu, it does the job if you understand how it works !
    I ended up doing something like this:
    Code (CSharp):
    1.  
    2.                 GenericDropdownMenu men = new GenericDropdownMenu();
    3.                 men.contentContainer.Add(secondaryContainer);
    4.                 men.GetRootContainer().Q<ScrollView>().style.maxHeight = maxContentHeightPx;
    5.                 Rect targetRect = this.LocalToWorld(mainContainer.contentRect);
    6.                 // Add 2 px for offset to main container, 2 pixels to take in consideration the 1 + 1 px borders of the mainContainer not taken into acount
    7.                 // Offset the x from 1 behind otherwise the width would be overflowing
    8.                 targetRect.Set(targetRect.x - 1, targetRect.y + 2, targetRect.width + 2, targetRect.height);
    9.                 men.DropDown(targetRect, this, anchored: true);
    mainContainer is the main part of the dropdown (the field) and secondaryContainer is the dropdown menu.