How to make UI block raycats (mobile)

Hi All

I’ve got code set up where a raycast is shot out into the scene only if there is no UI under it. It works fine in the editor using the mouse, but when I send to my Android device it doesn’t work - I can touch an object through the UI and it changes colour as per the below script.

Is there a special trick to achieving this on mobile / touch driven scenes?

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

public class RaycastTest : MonoBehaviour {

    public Camera mainCamera;

    // Use this for initialization
    void Start () {
   
    }
   
    // Update is called once per frame
    void Update () {

        if (EventSystem.current.IsPointerOverGameObject() == false)
        {
            Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;

            if (Physics.Raycast(ray, out hit, Mathf.Infinity))
            {
                hit.transform.renderer.material.color = Color.red;
            }         
        }         
    }
}
EventSystem.current.IsPointerOverGameObject()

This takes an optional argument for pointer id. each touch gets an incremental id. So first touch is 1, second is 2 ect. If you don’t pass an argument it just assumes left mouse click.

Hi Tim

Is there any other settings which could interfere with this?

I’ve tried passing in a few different arguments (0, 1, 2, 3) but the behavior persists.

I’m not from a programming background so there’s a chance I’m just misinterpreting your post but I modified my code a bit to be wrapped up in a click / touch and added the argument for pointer ID but the touch still passes through the UI and changes the colour of the object behind it.

    void Update () {

        if (Input.GetMouseButtonDown(0))
        {

            if (!EventSystem.current.IsPointerOverGameObject(1))
            {
                Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition);
                RaycastHit hit;

                if (Physics.Raycast(ray, out hit, Mathf.Infinity))
                {
                    hit.transform.renderer.material.color = Color.red;
                }         
            }         
        }
    }
}

In the Event System I have ‘Allow Activation on Mobile Device’ and ‘Allow Activation on Standalone’ both ticked.

Thanks

I dont think “if(Input.GetMouseButtonDown(0))” will allow your code to run on mobile because a finger touch should cause that if to be false. I’d put a debug (or break point) inside that if to see if your even running the code you think you are.

Thanks Phil, I’ll double check now but it wasn’t working before I wrapped it up in that if statement either, so I don’t think that’s the problem. I’ll reply back here with the results.

Yeah so it still doesn’t work even when I remove the if statement (refer to the original code at the top).

This seems like a pretty fundamental part of the UI system - being able to block raycasts from entering the scene through the UI. So fundamental, in fact, that I’m convinced I must be doing something wrong. I’m actually kinda surprised that other people haven’t made their own threads discussing how to make it work?

Is there a solution to this? I’m having the same problem, it works on editor and emulator but when in real device, the touch just went through…

There are plenty of threads. And yes, you are doing something fundamentally wrong. Unity was just not nice enough to point out the changes properly in the docs.

The EventSystem and PhysicsRaycaster should replace raycasting for interaction with scene objects.

Its kind of a fundamental piece of information that was glossed over in the hype about the UI.

There is a video here that shows this. Skip forward to the third method if you like.

Hi, thanks for the video. Yes, there’re a lot of threads discussing about this problem but in every thread there’s always people replying that it’s not working. Sadly I don’t have device here, so I can’t test it right now.