Search Unity

How to make UI block raycats (mobile)

Discussion in 'UGUI & TextMesh Pro' started by Aurecon_Unity, Oct 3, 2014.

  1. Aurecon_Unity

    Aurecon_Unity

    Joined:
    Jul 6, 2011
    Posts:
    241
    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?

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using UnityEngine.EventSystems;
    4.  
    5. public class RaycastTest : MonoBehaviour {
    6.  
    7.     public Camera mainCamera;
    8.  
    9.     // Use this for initialization
    10.     void Start () {
    11.    
    12.     }
    13.    
    14.     // Update is called once per frame
    15.     void Update () {
    16.  
    17.         if (EventSystem.current.IsPointerOverGameObject() == false)
    18.         {
    19.             Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition);
    20.             RaycastHit hit;
    21.  
    22.             if (Physics.Raycast(ray, out hit, Mathf.Infinity))
    23.             {
    24.                 hit.transform.renderer.material.color = Color.red;
    25.             }        
    26.         }        
    27.     }
    28. }
     
  2. Tim-C

    Tim-C

    Unity Technologies

    Joined:
    Feb 6, 2010
    Posts:
    2,225
    Code (csharp):
    1.  
    2. EventSystem.current.IsPointerOverGameObject()
    3.  
    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.
     
  3. Aurecon_Unity

    Aurecon_Unity

    Joined:
    Jul 6, 2011
    Posts:
    241
    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.

    Code (CSharp):
    1.     void Update () {
    2.  
    3.         if (Input.GetMouseButtonDown(0))
    4.         {
    5.  
    6.             if (!EventSystem.current.IsPointerOverGameObject(1))
    7.             {
    8.                 Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition);
    9.                 RaycastHit hit;
    10.  
    11.                 if (Physics.Raycast(ray, out hit, Mathf.Infinity))
    12.                 {
    13.                     hit.transform.renderer.material.color = Color.red;
    14.                 }        
    15.             }        
    16.         }
    17.     }
    18. }
    In the Event System I have 'Allow Activation on Mobile Device' and 'Allow Activation on Standalone' both ticked.

    Thanks
     
  4. phil-Unity

    phil-Unity

    Unity UI Lead Developer

    Joined:
    Nov 23, 2012
    Posts:
    1,226
    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.
     
  5. Aurecon_Unity

    Aurecon_Unity

    Joined:
    Jul 6, 2011
    Posts:
    241
    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.
     
  6. Aurecon_Unity

    Aurecon_Unity

    Joined:
    Jul 6, 2011
    Posts:
    241
    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?
     
  7. un_ity

    un_ity

    Joined:
    Oct 31, 2014
    Posts:
    5
    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..
     
  8. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    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.
     
  9. un_ity

    un_ity

    Joined:
    Oct 31, 2014
    Posts:
    5
    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.