Android touches pass through UI elements

Is there a way to prevent Android touches to pass through UI elements on a canvas? I’m using Unity 5.2.1f1.

Possible answers for non-tile map uses

Setup

  • 2d game.
  • An overlay canvas with
    buttons.
  • A gameobject input handler
    that checks for world input on the
    update method. Input through this
    method checks the world for
    interactivity.

Why do I check for world objects based at a location? I’m using a tile map that dynamically loads tiles and the system has a simple method to convert a world location to a specific tile location on the map. The tiles do not have any events on them.

Desktop and Editor Work

Grab from the update method Input.mousePosition if the pointer is not over a game object.

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

Android Build Doesn’t Work

Grab the first touch. If it has ended check if the pointer is over an object.

Touch touch = Input.GetTouch(0);

			if( touch.phase == TouchPhase.Ended )
			{
				//prevent touch through
				if(	EventSystem.current.IsPointerOverGameObject(touch.fingerId) )
				return false;

				vec = touch.position;
				return true;
			}

I’ve also tried looping over touches. IsPointerOverGameObject appears to be useless for preventing Android touches from passing through UI canvas objects.

Android Build Work Around

The only way I’ve found how to work around this issue, thanks to Fattie, is to check for a selected gameobject in the event system.

if( EventSystem.current.currentSelectedGameObject != null ) return false;

Is there a better way to do this? The only tutorials I’ve seen that might relate require an event interface for the tiles in the tile map and any game object agents acting “on top” of the tile map.

I’ve spent about my whole afternoon reading forum posts about this issue and have not come way with a better solution.

Some discussions

http://forum.unity3d.com/threads/ui-not-working-5-1-1-5-2-0b1.339462/#post-2195414

http://forum.unity3d.com/threads/upgrading-to-unity-5-2-ui-problem-with-raycast-target.353586/

http://gamedev.stackexchange.com/questions/90196/how-to-detect-that-user-has-touched-ui-canvas-in-unity-4-6

using UnityEngine.EventSystems;
using System.Collections.Generic;

private bool IsPointerOverUIObject() {
		PointerEventData eventDataCurrentPosition = new PointerEventData(EventSystem.current);
		eventDataCurrentPosition.position = new Vector2(Input.mousePosition.x, Input.mousePosition.y);

	List<RaycastResult> results = new List<RaycastResult>();
	EventSystem.current.RaycastAll(eventDataCurrentPosition, results);
	return results.Count > 0;
}

I found this solution from _metiss

Using a simple if statement lets you check if you’re over any ui element or the main game.

	if (!IsPointerOverUIObject())

It’s a very annoying problem and it seems like the forums are filled with part or incorrect answers, and I’m not expert but I have found that this specific function works best for me.

if (EventSystem.current.IsPointerOverGameObject() ||
EventSystem.current.currentSelectedGameObject != null) {
return;
}

Works for me here on Android ( with Unity 5.3.1f1 )

I made this solution:

using UnityEngine.EventSystems;
...

if (EventSystem.current.currentSelectedGameObject == null) { 
			//not toch UI
}

if you have a panel or something you want block only add button component, and changue color tint to none

using UnityEngine.EventSystems;

    Vector2 touchPos;
    public GraphicRaycaster GR;
    
    void Update()
    	{
    		if(Input.touchCount > 0)
    		{
    			if(Input.GetTouch(0).phase == TouchPhase.Began)
    			{
    				PointerEventData ped = new PointerEventData(null);
    				ped.position = Input.GetTouch(0).position;
    				List<RaycastResult> results = new List<RaycastResult>();
    				GR.Raycast(ped, results);
    				if(results.Count == 0)
    				{
                                      // YOUR CODE HERE
    				}
    			}
    		}
    	 }

I just had to share this solution. I am using touch controls for android to move selected units by simply touching a spot on the screen. Like many other people I had issues with my touches going through my UI. I could not find a working solution on the forums but I found one in the “yonder”. Any code that you put in the designated if statement will return true only if you’re not pressing on a GUI element. You can similarly return the UI elements under your touch. I selected the only GraphicRaycaster in my scene from my one canvas object in the inspector. I worked out my solution from info found here.
Check it out @ecesis_llc

@ecesis_llc

So I haven’t been able to find a way that makes more sense than this, but hey for now it works rather well for me.

So I was having the same problem, clicking on my UI would cause things to be built underneath the UI where the player did not want things to show up. So here is what I did.

On the Camera that is used for said RayCasting I created a 3D Cube Object and made it the child of the camera. I made it fit as snug as I could to the area in which I wanted blocked, now obviously you can use whatever shape you want. So now you don’t want this to be an eyesore right, so just delete or diable the mesh rendered and set the Z axis to 0. This will cause the raycast to hit the ghosted 3D Collider before anything else. Hope it helps at least until a better solution is found for ya.

Because the forums seem filled with half solutions and I had to search for hours to fix it my solution is as follows:

if (UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject () == false) {
              currentDestination = clickPoint, 
	}

So the Raycaster only sets click point to be the current destination if the point is not pointed at a “Game Object” i.e. a UI element. Inside of a switch statement, it works well on Android build.

Hope it helps,
Kit