Search Unity

"Blocks Raycast" in Canvas Group necessary for gameObject to be Interactable?

Discussion in 'UGUI & TextMesh Pro' started by kfielding, Mar 20, 2020.

  1. kfielding

    kfielding

    Joined:
    Jun 7, 2017
    Posts:
    2
    I have a large instagram-feed-like scrollview (actually InfiniteScroll) and I want to have an invisible button blanket layer over each card in order to know when people are trying to tap on the different cards. However, I also want users to be able to play/pause some the cards that play music or video etc.

    It seems that if I add "Blocks Raycast" + "Interactable" and to the Canvas Group of the invisible button blanket over top of the card, the button blanket receives the interaction click no problem. However if I disable "Blocks Raycast" it no longer works, despite "Interactable" still being checked.

    Why is this? Is there any way to use button.onClick.AddListener style listeners to multiple gameObjects on top of eachother and actually have them all individually catch the onClick event?

    The workarounds are very sloppy (Update() method and raycast colliding).

    Thanks,
    Kevin
     
  2. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,096
    I was curious and checked it myself.
    The behavior is indeed not very intuitive.
    When interactable is off the selectibles below will do a transition to the disabled state. If Blocks Raycast is on, it doesn't matter if interactable is enabled or not, the clicks will go through and elements inside will not receive any clicks.

    So, this way you cannot click two things at once.

    What you would need to do is replacing the EventSystem with your custom Event system. There you can perform another raycast to receive all elements under the mouse. You could check a tag or something on them to see if they should be clicked even when behind another element.

    here is a starting point:
    Code (CSharp):
    1. public class CustomEventSystem : EventSystem
    2. {
    3.     List<RaycastResult> raycastResult = new List<RaycastResult>();
    4.  
    5.     protected override void Update()
    6.     {
    7.         base.Update();
    8.  
    9.         PointerEventData pointer = new PointerEventData(this);
    10.         pointer.position = Input.mousePosition;
    11.  
    12.         RaycastAll(pointer, raycastResult);
    13.  
    14.         // raycastResult has now the information of what is under the mouse. do something with that information.
    15.     }
    16. }