How to prevent Touch Events from propagating through Canvas button

I have a scene with a overlay canvas containing a button.
Also in my scene are custom buttons detecting Touch events
When I click the Canvas button, the Touch event propagates through the Canvas and is detected by the custom buttons directly ‘underneath’ the Canvas button.

How can I prevent this from happening?

Personally I do it this way. When TouchPhase.Began is returned, I do the following check and if it returns true I invalidate the touch. What are your custom buttons? Perhaps it will play nice.

using UnityEngine.EventSystems;

if (EventSystem.current.IsPointerOverGameObject ())
{
    //touch is invalid
}

Trying a variation which isn’t working

//only select if not over other gameObject or UI element
            if (!EventSystem.current.IsPointerOverGameObject())
            {

Was hoping there would be a solution that simply modified the overlay Canvas button instead of having to modify your custom buttons responding to Touches.

Can you post your custom buttons code?

I’m using LeanTouch, more specifically extending the LeanSelectable class after making the Select method virtual. Since its free guess its ok to post. Any feedback appreciated!

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using Lean.Touch;
public class TileSelect : LeanSelectable,IEventListener
{
      private bool _selected;
    public bool HandleEvent(IEvent evt)
    {
        return false;
    }
    void Awake()
    {
        _selected = false;
        isSelected = false;
        EventManager.Instance.AddListener(this, "Event_Init", OnInit);
 
    }
    private bool OnInit(IEvent evt)
    {
        return false;
    }
  
    override public void Select(LeanFinger finger)
    {
        if (_selected == false)
        {
            //only select if not over other gameObject or UI element
            if (!EventSystem.current.IsPointerOverGameObject())
            {
                base.Select(finger);
                isSelected = true;
                //OnSelect.Invoke(finger);
                Debug.Log("0 :ASSERT TileSelect" + name);
            }
        }
    }
}
using UnityEngine;
using UnityEngine.Events;

namespace Lean.Touch
{
    // This component allows you to select this GameObject via another component
    public class LeanSelectable : MonoBehaviour
    {
        // Event signature
        [System.Serializable] public class LeanFingerEvent : UnityEvent<LeanFinger> {}

        [Tooltip("Should IsSelected temporarily return false if the selecting finger is still being held?")]
        public bool HideWithFinger;

        public bool IsSelected
        {
            get
            {
                // Hide IsSelected?
                if (HideWithFinger == true && isSelected == true && SelectingFinger != null)
                {
                    return false;
                }

                return isSelected;
            }
        }

        // This stores the finger that began selection of this LeanSelectable
        // This will become null as soon as that finger releases, which you can detect via OnSelectUp
        [System.NonSerialized]
        public LeanFinger SelectingFinger;

        // Called when selection begins (finger = the finger that selected this)
        public LeanFingerEvent OnSelect;

        // Called when the selecting finger goes up (finger = the finger that selected this)
        public LeanFingerEvent OnSelectUp;

        // Called when this is deselected, if OnSelectUp hasn't been called yet, it will get called first
        public UnityEvent OnDeselect;

        // Is this selectable selected?
        [SerializeField]
        public bool isSelected;

        [ContextMenu("Select")]
        public void Select()
        {
            Select(null);
        }

        virtual public void Select(LeanFinger finger)
        {
            isSelected      = true;
            SelectingFinger = finger;

            OnSelect.Invoke(finger);
        }

        [ContextMenu("Deselect")]
        virtual public void Deselect()
        {
            if (SelectingFinger != null)
            {
                OnSelectUp.Invoke(SelectingFinger);

                SelectingFinger = null;
            }

            isSelected = false;

            OnDeselect.Invoke();
        }

        protected virtual void OnEnable()
        {
            // Hook events
            LeanTouch.OnFingerUp += OnFingerUp;
        }

        protected virtual void OnDisable()
        {
            // Unhook events
            LeanTouch.OnFingerUp -= OnFingerUp;

            if (isSelected == true)
            {
                Deselect();
            }
        }

        private void OnFingerUp(LeanFinger finger)
        {
            // If the finger went up, it's no longer selecting anything
            if (finger == SelectingFinger)
            {
                OnSelectUp.Invoke(SelectingFinger);

                SelectingFinger = null;
            }
        }
    }
}

Your tiles are just regular gameobjects with a sprite renderer? Or UI objects with an image?

just Quads…with mesh Renderer.

Also using a forked version of ARkit using 2 cameras to scale content https://bitbucket.org/Unity-Technologies/unity-arkit-plugin/branch/alt-scaled-content

Not sure if that might be the issue.

If your canvas is set to overlay I doubt it, maybe worth investigating.

Does LeanFinger contain the fingerId from the touch class? If so, try passing it to IsPointerOverGameObject () as a parameter (the fingerId that is). I think that’ll fix it.

Sorry to have you jumping through hoops, honestly I’m not too sure what’s going wrong if the rest of your stuff isn’t unity UI inherited. The check should return true. It’s straight up returning false even if the touch is performed over a UI object (with raycast target enabled)?

Thanks will give that a try