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

Catch "tap input" before Dropdown's blocker

Discussion in 'Scripting' started by molosev, Nov 16, 2020.

  1. molosev

    molosev

    Joined:
    May 24, 2014
    Posts:
    11
    Hello,

    I display an in-game manual which integrates a Dropdown.
    At the top right of the page I display a button that should close the manual window.
    My problem is that when the dropdown list is shown if I tap the close button it is the dropdown blocker which receives the input and not my button (which is however placed in front in the hierarchy). And so the list disappears and my window doesn't close.

    I tried extending the Dropdown class to catch the event but I am not getting the result I want.

    Do you have any ideas ?

    Thank you !
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,762
    Ideas:

    - make the dropdown blocker smaller

    or

    - put another close up for when the dropdown blocker is active

    or

    - put an invisible close on the dropdown page that knows how to tell the real page to close

    etc.
     
    molosev likes this.
  3. molosev

    molosev

    Joined:
    May 24, 2014
    Posts:
    11
    Thank you for all these ideas !
    I'll try it.
     
  4. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,833
    Debugging Tip: If you play your game inside the Unity editor and select the Event System object in your hierarchy, then at the bottom of the inspector you will see some real-time debugging information while you play. Among other things, this will tell you what object Unity thinks the mouse is currently pointing at.


    I'm not aware of any situation in which object A would be drawn on top but object B would get input priority in the space where they overlap. This makes me think that either (a) there is something wrong with object A that prevents it from working at all (e.g. if "raycast target" is turned off, or if it's in a separate Canvas that doesn't have a Graphic Raycaster component), or (b) object B is actually being drawn in front, and there's some sort of optical illusion making you think otherwise, or (c) you're not giving the input you think you're giving.

    One thing that occurs to me is that Unity's default drag threshold makes it very easy for a "tap" to be misinterpreted as a drag when using a touchscreen (at least, in my opinion). So for example, if you had a Button inside of a ScrollRect, you might find that your attempts at taps keep getting interpreted as drags, which get passed up the hierarchy to the ScollRect and interpreted as scrolls, preventing you from pressing the Button. But it seems unlikely that your close-button is a child of the dropdown in your object hierarchy...
     
    molosev and Kurt-Dekker like this.
  5. molosev

    molosev

    Joined:
    May 24, 2014
    Posts:
    11
    You are right, even if the code tells the button to be placed in front of the blocker and I can see it organized in this order in the hierarchy window (the close button is moved at the bottom of the list), if I change the color of the blocker so that it becomes visible or if I observe what is pointed in the EventSystem window, it is still the blocker which is in front.

    Here is the code I am using:
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3.  
    4. public class ManualDropdown : Dropdown
    5. {
    6.     protected override GameObject CreateBlocker(Canvas rootCanvas)
    7.     {
    8.         GameObject closeManualButton = GameObject.Find("CloseManualButton");
    9.         GameObject blocker = base.CreateBlocker(rootCanvas);
    10.         blocker.GetComponent<Image>().color = new Color(0.8f, 0.8f, 0.8f, 0.5f);
    11.         closeManualButton.transform.SetParent(rootCanvas.transform);
    12.         closeManualButton.transform.SetSiblingIndex(blocker.transform.GetSiblingIndex() + 1);
    13.         return blocker;
    14.     }
    15. }
    If it worked it would be an easy solution to implement. It is an application that will be displayed on different screen sizes and I cannot test on all these devices so the solution of changing the size of the blocker seems a little dangerous to me ...

    Thanks to your remark I just noticed that the Blocker has its own Canvas and that its Sort Order value is very high (29'999).
    I added this line and it works now:
    Code (CSharp):
    1. blocker.GetComponent<Canvas>().overrideSorting = false;
    I just have to find a way to tell the close button to return to its place once the Manual is closed.

    Thank you !
     
    Last edited: Nov 22, 2020