10

I am making a Unity3d mobile application. And I have a problem: How to detect touch on UI, or not?

I tried this (but it doesn't work):

UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject();

and this:

private static List<RaycastResult> tempRaycastResults = new List<RaycastResult>();

public bool PointIsOverUI(float x, float y)
{
    var eventDataCurrentPosition = new PointerEventData(EventSystem.current);

    eventDataCurrentPosition.position = new Vector2(x, y);

    tempRaycastResults.Clear();

    EventSystem.current.RaycastAll(eventDataCurrentPosition, tempRaycastResults);
    
    return tempRaycastResults.Count > 0;
}
Chris Schaller
  • 13,704
  • 3
  • 43
  • 81
Knaus Irina
  • 789
  • 5
  • 15
  • 35
  • Possible duplicate of [What is the most elegant way to let UI objects swallow touches in unity 5?](http://stackoverflow.com/questions/35381222/what-is-the-most-elegant-way-to-let-ui-objects-swallow-touches-in-unity-5) – Fattie Feb 15 '16 at 17:26

3 Answers3

23

For mobile you need to pass the id of the Touch to IsPointerOverGameObject

foreach (Touch touch in Input.touches)
{
    int id = touch.fingerId;
    if (EventSystem.current.IsPointerOverGameObject(id))
    {
        // ui touched
    }
}
Chris Schaller
  • 13,704
  • 3
  • 43
  • 81
Marius Junak
  • 1,203
  • 10
  • 17
  • 1
    I ran afoul of this recently. Oddly enough, in my project, in Unity 5.3.x `EventSystem.current.IsPointerOverGameObject()` worked fine in iOS (and Android!), but at least in Unity 5.4.0f3, I had to add an id (in my case `0` was fine) for iOS, but not for Android. – livingtech Aug 23 '16 at 21:43
1

Please try this :

// for Android check differently :

if(EventSystem.current.IsPointerOverGameObject(0) return false;

// for windows check as usual :

if (EventSystem.current.IsPointerOverGameObject())
    return false;
jpyams
  • 4,030
  • 9
  • 41
  • 66
  • If you use IsPointerOverGameObject() without a parameter, it points to the "left mouse button" (pointerId = -1); therefore when you use IsPointerOverGameObject for touch, you should consider passing a pointerId to it. https://docs.unity3d.com/2018.2/Documentation/ScriptReference/EventSystems.EventSystem.IsPointerOverGameObject.html – CrandellWS Feb 27 '21 at 02:11
0

Add this to the clickable object

private MyUIHoverListener uiListener;
private Vector3 mousePos;
    
private void OnMouseDown()
{
    mousePos = Input.mousePosition;
    Debug.Log(Input.mousePosition);
}
private void OnMouseUp()
{
    //this part helps to not trigger object when dragging
    mousePos -=  Input.mousePosition;
    //Debug.Log(mousePos);
    
    if(mousePos.x < 3 && mousePos.y < 3 
        && mousePos.z < 3 && mousePos.x > -3 
        && mousePos.y > -3 && mousePos.z > -3)
    {
        //Debug.Log("NOT MOVED");
        if (!GameMan.ObjectClickBlocker)
        {
            if (uiListener.IsUIOverride)
            {
                //Debug.Log("Cancelled OnMouseDown! A UI element has override this object!");
            }
            else
            {
                // Debug.Log("Object OnMouseDown");
                StartCoroutine(LoadThisBuilding(0));
                ToggleBuildingMenu();  
            }
        }
    }
}

Add this on the object in front of the clickable object:

public class MyUIHoverListener : MonoBehaviour
{
    [SerializeField]
    public bool IsUIOverride { get; private set; }

    void Update()
    {
        // It will turn true if hovering any UI Elements
        IsUIOverride = EventSystem.current.IsPointerOverGameObject();
    }
    void OnDisable()
    {
        IsUIOverride = false;}
    }
}
Chris Schaller
  • 13,704
  • 3
  • 43
  • 81
2winners
  • 1
  • 1