Click should interact with multiple overlayed UI images

Hi there,

I’m making a graphic adventure style game and I have a hierarchy, under a canvas, that looks like this:

ButtonContainer

Button1

Button2
OverlayPopup
ClickableLayer

Text

Every time I click Button1 I display the OverlayPopup containing some text. I want to make the OverlayPopup disappear when I click everywhere on the screen, so I’ve attached to the ClickableLayer a transparent stretched image with a script that disables the OverlayPopup. Everything works fine right now, but I want to add the fact that if I click Button2 a different popup opens up, but the OverlayPopup still is disabled (if it’s active).


I can do this in a million ways, but I want to avoid the buttons to know anything about the popups and I wanted to make the popups atomic if possible. The thing I thought was smarter was to use a canvas group with Blocks Raycast unchecked, so that I could interact with the ClickableLayer and with Button2 with the same click, but this appears to be not working with UI. Is there a way to get the interaction from an image but avoid blocking the graphic raycaster, so that it can still interact with other UI components that are underneath that image?

I’ve found this page that explains how to customize the event system using the GraphicRaucaster.
I’ve modified the script in the link to my needs, to propagate the click on all ui behaviour that are underneath the clicked one. The script is something like this and needs a GeaphicRaycaster, that I have attached to my canvas.

public class ClickableLayer : MonoBehaviour, IPointerClickHandler {
        private GraphicRaycaster _graphicRaycaster;
       
        private void Start()
        {
            _graphicRaycaster = GetComponentInParent<GraphicRaycaster>();
        }

        public void OnPointerClick(PointerEventData eventData)
        {
            List<RaycastResult> results = new List<RaycastResult>();
            _graphicRaycaster.Raycast(eventData, results);
            foreach (RaycastResult result in results)
            {
                if(eventData.pointerCurrentRaycast.depth > result.depth)
                {
                    ExecuteEvents.ExecuteHierarchy(result.gameObject, eventData, ExecuteEvents.pointerClickHandler);
                }
            }
                
            Hide();
        }
  }

Hope this helps somebody :smiley: