• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
31
Question by djneon · Sep 04, 2014 at 01:19 AM · 4.6

How do I block touch events from propagating through Unity.UI ?

There's a huge basic problem with Unity.

If I touch a UI Panel, Button, etc and there's a game object underneath it,

the game object receives an input event.

I don't want this behavior and nobody does. Incredibly it seems UI does not "catch" input events. What to do?

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

8 Replies

· Add your reply
  • Sort: 
avatar image
40
Best Answer

Answer by Kiwasi · Sep 26, 2014 at 10:41 AM

There are three ways to do this, as demonstrated in this video tutorial.

  1. Use EventSystem.current.IsPointerOverGameObject

  2. Convert your OnMouseXXX and Raycasts to an EventSystem trigger. Use a physics raycaster on the camera

  3. Implement the various handler interfaces from the EventSystems namespace. Use a physics raycaster on the camera.

Number one is easiest for a quick and dirty solution. Number three is far more powerful, and I would recommend it as the default for all new projects.

Edit:Totally removed the old answer and put up a new one. Sorry if that's killed the comments.

Comment
Add comment · Show 7 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Kiwasi · Jan 26, 2015 at 06:27 AM 0
Share

http://docs.unity3d.com/$$anonymous$$anual/script-PhysicsRaycaster.html

There is also an appropriate version for 2D

avatar image Kiwasi · Jan 26, 2015 at 06:52 AM 0
Share

Your missing it. There are three new components introduced in 4.6

  • GraphicsRaycaster. This is used to detect clicks on the UI

  • PhysicsRaycaster. This is used to detect clicks on colliders

  • Physics2DRaycaster. This is used to detect clicks on collider2D

All if these components process through the EventSystem. The EventSystem will choose which raycaster has priority, depending on rendering order (this is still a little buggy, but it gets better each patch).

This means that Physics.Raycast is no longer needed for detecting inputs over a GameObject. It also makes On$$anonymous$$ouseXXX redundant.

avatar image Kiwasi · Jan 26, 2015 at 07:49 AM 0
Share

The video link in my answer explains the basics or click blocking. It's enough to give a competent programmer a place to start. I plan to do a complete intro for the event system, but I haven't got to it yet.

avatar image emilian-s · Jul 28, 2016 at 05:33 PM 0
Share

The no.3 option works like a charm.

But I have a question. How can I disable pointer events so they can pass thru an gameobject?

In my case I have two gameobject on top of each other, and in some cases I need to catch PointerDown on the bottom one.

Thank you.

avatar image krstrobe emilian-s · Jul 28, 2016 at 06:38 PM 0
Share

Check out my post at the bottom. simplest fix ever!

avatar image emilian-s emilian-s · Jul 28, 2016 at 08:44 PM 0
Share

Your solution doesn't help in my case.

After more research I figure it out. On Camera > Physics Raycaster > Event mask, I've choose only Default layer. This means that only game object that are on Default layer will catch events. The game objects that I don't want to catch events, I move them on a different layer.

avatar image krstrobe emilian-s · Jul 29, 2016 at 02:53 PM 0
Share

Awesome! Glad that worked for you!

avatar image
16

Answer by Fattie · Jan 25, 2015 at 06:25 AM

From 2015 onwards simply do this:

br>

1) You'll have an EventSystem in the hierarchy already.

2) Add an empty game object with a collider, bigger than the screen. Call the object "draw". Make the layer "Draw". In Physics Settings make that layer interact with nothing.

If the camera moves around, you my wish to add this object simply under the camera; it will move with the camera. (If you think about it, this collider represents the "actual glass of the user's phone".)

3) Add a physics raycaster to the camera. One click. Click the event mask, uncheck everything and check only the the "Draw" layer.

4) Have the following script on the "draw" object. You're done.

...

 using UnityEngine;
 using System.Collections;
 using UnityEngine.EventSystems;
 
 public class FingerMove:MonoBehaviour,
         IPointerDownHandler, IDragHandler, IPointerUpHandler
     {
     public void OnPointerDown (PointerEventData data)
         {
         Debug.Log("FINGER DOWN");
         prevPointWorldSpace =
                 theCam.ScreenToWorldPoint( data.position );
         }
     
     public void OnDrag (PointerEventData data)
         {
         thisPointWorldSpace =
                theCam.ScreenToWorldPoint( data.position );
         realWorldTravel =
                thisPointWorldSpace - prevPointWorldSpace;
         _processRealWorldtravel();
         prevPointWorldSpace = thisPointWorldSpace;
         }
      
     public void OnPointerUp (PointerEventData data)
         {
         Debug.Log("clear finger...");
         }

Now if you're just detecting finger on the "glass" - so, you don't care about the user touching objects in the scene, you're just interested in swipes on the glass. (Example, touch to orbit the camera.) Here's the script - couldn't be easier ...

 using UnityEngine;
 using System.Collections;
 using UnityEngine.EventSystems;
 
 public class FingerMove:MonoBehaviour, IPointerDownHandler, IDragHandler, IPointerUpHandler
     {
     private Vector2 prevPoint;
     private Vector2 newPoint;
     private Vector2 screenTravel;
     
     public void OnPointerDown (PointerEventData data)
         {
         Debug.Log("FINGER DOWN");
         prevPoint = data.position;
         }
 
     public void OnDrag (PointerEventData data)
         {
         newPoint = data.position;
         screenTravel = newPoint - prevPoint;
         _processSwipe();
         }
 
     public void OnPointerUp (PointerEventData data)
         {
         Debug.Log("FINEGR UP...");
         }
     
     private void _processSwipe()
         {
         // your code here
         Debug.Log("screenTravel left-right.. " + screenTravel.x.ToString("f2"));
         }
     
     }



It's that simple.

It ignores clicks on the UI. Hooray.

Much discussion and examples...

https://stackoverflow.com/q/40323677/294884

https://stackoverflow.com/a/35530316/294884

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image blamejane · Dec 27, 2016 at 05:17 PM 0
Share

@Fattie Trying to follow your 2015 example with IPointerClickHandler ins$$anonymous$$d of IPointerDown/Up, but can't get it working. I followed steps 1 (3d physics raycast) and step 2 with this method on Finger$$anonymous$$ove (but never see any debug to console when I click or touch the screen.

     public void OnPointerClick (PointerEventData eventData)
     {
         Debug.Log("OnPointerClick");
 
     }
avatar image adamonline45 blamejane · Aug 28, 2017 at 04:20 AM 0
Share

@blamejane A little late, but I found I had to implement IPointerDownHandler and IPointerUpHandler to get IPointerClickHandler working.

avatar image
0

Answer by krstrobe · Jul 12, 2016 at 05:33 PM

Everyone! Here is what solved everything for me! All of this scripting and event stuff gave me trouble. So I thought, what if when I bring up the ui I bring up a 3d object with a collider because those block other objects and input. I put a cube under my main canvas and I have my ui showing and hiding on a mouse click. Now the cube shows up as well and it stops clicks! I didn't want it physically blocking me so I checked the "is trigger" check box on the box collider. I also turned off the mesh renderer so now it is completely invisible and blocks everything. This solved my background click interactions and it solved my ui mouse clicks from locking the mouse back to the center! This was easy easy and works like a charm! At least in the editor. I hope it helps everyone!

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by colorpillar · Aug 16, 2016 at 05:03 PM

Hi there, if you are working with the UI system you can create a touch-blocker which blocks everything underneath it by using a very simple graphic data type.

Create a new Component with this code:

 using UnityEngine;
 using UnityEngine.UI;
 public class SimpleGraphic : Graphic 
 {
     protected override void Start () 
     {
         material.color = Color.white;
     }
 }

Now create a GameObject and add the component.

This is a component based on the UI.Graphic type which is the base for the UI.Image or UI.Text types. It therefore shares the base functionality but does not have the bloated array of tools that these other types provide. It will still let you choose to allow rayCast or not (block or not). As an example you can have a G.O. wth this Comp sit at the top of the siblings list. Objects that are arranged below it will appear above it and are 'clickable', those arranged above it are not, neither are any ray-cast-targetable parent-nodes. If you wish to have it act as a full-screen blocker add a RectTransform to your G.O. and use the stretching/anchoring options. The Color setting is just to visualise that it is actually there. Adjust the alpha for transparency. Hope this helps

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by sefiroths · Aug 17, 2016 at 01:14 PM

I have tryed all suggestions but for my kind of problem this doesn't work: I have an image larger than the screen that I'd like to move dragging the finger moving the camera. An UI with buttons.

In the camera script I have:

 void LateUpdate () 
     {
 
         if (EventSystem.current.IsPointerOverGameObject ()) {
 //        if( EventSystem.current.currentSelectedGameObject != null ) {
             Debug.Log ("wwwwwwwwwwwww");
         }
 
         if (SystemInfo.deviceType == DeviceType.Handheld) {
             Touch touch;
             if (Input.touchCount == 1 && Input.GetTouch (0).phase == TouchPhase.Moved) {
                 touch = Input.GetTouch (0);
                 x += touch.deltaPosition.x * xSpeed * 0.02f;
                 y -= touch.deltaPosition.y * ySpeed * 0.02f;
     

that moves the camera. When I drag the finger starting from an UI element the camera moves!!!! AND

 EventSystem.current.IsPointerOverGameObject ()) {
 if( EventSystem.current.currentSelectedGameObject != null )

detect the element only when the finger is released, if the finger is released outside the UI element currentSelectedGameObject is not null blocking everything

 OnMouseXXX and Raycasts to an EventSystem trigger

should be inside the gameobject that I don't want to select if is under another object, but I want to block the movement of the camera... Can someont put me on the right direction? thanks

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image DientesDeCheto · Aug 17, 2016 at 03:32 PM 0
Share

Hi @sefiroths,

it's a half year ago since I had no time to do anything in Unity, but, I remember that there have been several solutions to such type of problems. I think on the Canvas was an option to avoid underneath objects to be triggered. In my Case I had an $$anonymous$$enu over another, and the underneath button was pressen as soon as you touched the menu. Here you can find the Property Recieves Event, what sets the processing of events by the specific canvas: https://docs.unity3d.com/$$anonymous$$anual/class-Canvas.html

Here you can find CanvasGroup: https://docs.unity3d.com/$$anonymous$$anual/class-CanvasGroup.html There's a Property named Interactable, try using it.

Try some of theses, I'm pretty shure that I also used some of theses in combination with some own script, such as canvasDisabler.

So the best way, if none of those example-Links work, should be disabling the underneath canvas while the image is in front of the canvas?

BR Tell me if it worked and what worked :D

  • 1
  • 2
  • ›

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.



Follow this Question

Answers Answers and Comments

31 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

New UI system. How to focus on input fields. 6 Answers

4.6UI Rect Transfrom fix 1 Answer

Unity 4.6 beta button with Javascript rather than C# 2 Answers

Is it possible to start a coroutine using a button from the new UI system (4.6) 1 Answer

Unity 4.6 adding a Canvas Text onto a gameobject prefab?? -1 Answers

  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges