check if the touched area on the screen is part of the UI in Enhanced Touch?

Hello,

I have this InputHandler that gets touch events from EnhancedTouch and then raises its own touch events for the rest of my game to consume.

I want to be able to distinguish whether the touch is a UI touch or not.

I know you can use the following with the regular input system:

foreach (Touch touch in Input.touches)
{
    int id = touch.fingerId;
    if (EventSystem.current.IsPointerOverGameObject(id))
    {
        // ui touched
    }
}

But when using enhanced touch, i dont have access to the fingerId in order to pass it to IsPointerOverGameObject. How can i go about checking whether my EnhancedTouch touches are over UI elements?

I tried to do the following:

public bool IsClickOnUI(Vector3 location)
{
    var worldPoint = _camera.ScreenPointToRay(location);

    RaycastHit hit;
    if (Physics.Raycast(worldPoint, out hit))
    {
        if (hit.transform.CompareTag("UI"))
        {
            return true;
        }
    }

    return false;
}

but it didnt work, which tells me that Physics.Raycast is completly ignoring the UI

For reference, this is my input handler:

using System.Runtime.CompilerServices;
using System.Runtime.InteropServices.ComTypes;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem.EnhancedTouch;
using UnityEngine.InputSystem;
using ETouch =  UnityEngine.InputSystem.EnhancedTouch;

public class InputHandler : MonoBehaviour
{
    private void OnEnable()
    {
        EnhancedTouchSupport.Enable();
        ETouch.Touch.onFingerDown += Touch_OnFingerDown;
        ETouch.Touch.onFingerMove += Touch_OnFingerMove;
        ETouch.Touch.onFingerUp += Touch_OnFingerUp;
    }

    private void OnDisable()
    {
        ETouch.Touch.onFingerDown -= Touch_OnFingerDown;
        ETouch.Touch.onFingerMove -= Touch_OnFingerMove;
        ETouch.Touch.onFingerUp -= Touch_OnFingerUp;
        EnhancedTouchSupport.Disable();
    }

    private void Touch_OnFingerDown(Finger touchedFinger)
    {
        if (!CameraManager.instance.IsClickOnUI(touchedFinger.screenPosition))
        {
            EventBus<OnFingerDownEvent>.Raise(new OnFingerDownEvent
            {
                finger = touchedFinger
            });
        }
    }

    private void Touch_OnFingerMove(Finger movedFinger)
    {
        if (!CameraManager.instance.IsClickOnUI(movedFinger.screenPosition))
        {
            EventBus<OnFingerMoveEvent>.Raise(new OnFingerMoveEvent
            {
                finger = movedFinger
            });
        }
    }

    private void Touch_OnFingerUp(Finger lostFinger)
    {
        if (!CameraManager.instance.IsClickOnUI(lostFinger.screenPosition))
        {
            EventBus<OnFingerUpEvent>.Raise(new OnFingerUpEvent
            {
                finger = lostFinger
            });
        }
    }
}

Hey, its me again, this will probably be a dead post, but im sure someone will come from 2-3 years in the future for this same issue, this is the only solution i found that works, basically u get the Finger.currentTouch.screenPosition, and pass it to this function:

    public bool IsClickOnUI(Vector3 location)
    {
        PointerEventData pointerEventData = new PointerEventData(EventSystem.current);
        pointerEventData.position = location;

        List<RaycastResult> results = new List<RaycastResult>();
        EventSystem.current.RaycastAll(pointerEventData, results);
        for (int i = 0; i < results.Count; i++)
        {
            if (results[i].gameObject.CompareTag("UI"))
            {
                return true;
            }
        }

        return false;
    }
1 Like

Thank you, this has saved hours of hacks. Took sooner that the expected 2-3 years.