1

I have my project setup like this:

Main Camera

  • Physics 2D Raycaster
  • Event Mask: Everthing

Canvas

  • Graphic Raycaster
  • Blocking Objects: None

Blocking Mask: Nothing

2 Objects setup:

  1. GameObject

    • Sprite Renderer

    • Rigidbody 2D

    • Circle Collider 2D

    • (my GO script)

  2. UI

    • Image

    • Button

    • (my UI script)

In both my GO and UI script, I add OnPointerEnter event. and both work fine on their own. I can receive OnPointerEnter event.

But when I use a joint to drag a GO object and move to top of the UI object. My UI object OnPointerEnter blocked by the GO. I cannot receive the UI OnPointerEnter event.

I search on web and everybody ask for blocking raycast on GO to UI. But I need the reverse, I want both GO and UI receive OnPointerEnter event no matter if they overlap or not. Any hints?

P.S. something like this in 2D version, GameObject block UI Object. But I still want to receive UI Object OnPointerEnter.

enter image description here

user1295050
  • 145
  • 1
  • 12
  • "My UI object OnPointerEnter blocked" I think you should explain this. What happens? What does it block? – Programmer Nov 06 '16 at 11:16
  • does it mean `OnPointerEnter` works for GO and UI alone? why don't you disable the other one as soon as drag started? – Bizhan Nov 06 '16 at 12:16
  • This is a really interesting question! You want touch to go to BOTH your .UI and your game object .... is that correct? – Fattie Nov 06 '16 at 13:14
  • Are you basically trying to drag a OBJECT IN THE SCENE (say "a robot") ON TO A DRAG TARGET IN .UI ? If so - awesome. – Fattie Nov 06 '16 at 13:15
  • Both GO and UI OnPointerEnter work on their own. I use a joint to drag the GO, so it has some movement delay to "chase" my pointer back. So, if I drag the GO "slowly" and enter the UI. NO OnPointerEnter received from the UI. If I drag the GO "fast" and the pointer quickly enter the UI before the GO "chase" and "block" the pointer between the pointer and UI. The UI OnPointerEnter received. Here is what I mean "blcoked". – user1295050 Nov 06 '16 at 13:18
  • Hi @user1295050, sure I've given you the full answer. Note that you need to use **TWO SYSTEMS** to make it happen. It is difficult to sync them, but fortunately I am here to explain it !!! :-) – Fattie Nov 06 '16 at 13:36
  • Note: very often (just for general reasons) it's better to put your .UI on a totally separate camera. You may wish to do that here just for clarity. IN all events don't forget to deal with your Layers properly. – Fattie Nov 06 '16 at 13:37
  • Hi Joe Blow, Thanks to your advice. I am working on it. BTW, someone suggest me to add Trigger system in the UI to detect the GO. Is it work to add trigger system in unity UI? P.S. my GO object already implement trigger system and work fine. P.S. I tried adding Trigger and didn't receive trigger event. – user1295050 Nov 06 '16 at 22:12
  • Done. Adding trigger system in UI (as component) work. (p.s. (as child) didn't work) – user1295050 Nov 06 '16 at 23:52

1 Answers1

2

Finally get what I want. Now I have 2 solutions:

  1. using OnTriggerEnter2D
  2. turn off Physics2DRaycaster LayerMask GO when dragging GO

1. using OnTriggerEnter2D

  1. When drag GO. Shoot event to UI and tell which GO is dragging.
  2. Add rigibody2D(isKinematic and Freeze xyz) and 2Dcollider(is trigger) as component in UI object.
  3. OnTriggerEnter2D receive my GO collider and check if it is the dragging GO.(doing this because I excatlly want the UI get my only dragging GO).

2. turn off Physics2DRaycaster LayerMask GO when dragging GO

  1. use this code: using UnityEngine.EventSystems; public void turnOffLayerMask(string layerMaskName) { Physics2DRaycaster p2drc = Camera.main.GetComponent(); LayerMask layerMask = p2drc.eventMask; LayerMask disableLayerMask = 1 << LayerMask.NameToLayer(layerMaskName); p2drc.eventMask = layerMask & ~disableLayerMask; }
    public void turnOnLayerMask(string layerMaskName) { Physics2DRaycaster p2drc = Camera.main.GetComponent(); LayerMask layerMask = p2drc.eventMask; LayerMask enableLayerMask = 1 << LayerMask.NameToLayer(layerMaskName); p2drc.eventMask = layerMask | enableLayerMask; }

  2. turn off GO layerMask when dragging GO. Turn On back when drag end. The raycast can go through GO to UI and receive OnPointerXXX events.

I think the EventSystem auto. choose EITHER Physical raycast or Graphic raycast to detect GO/UI objects. So you can only receive either one set of event(Non-UI/ UI). Is it correct? It seems that I search on web and many people using OnMouseXXX (or other method) instead of Event system(i.e. OnPointerXXX). So they can "touch through" GO to UI.

user1295050
  • 145
  • 1
  • 12
  • Hi Joe, I don't have nice code to do your step 4iii. I shoot event and tell dragging GO position to UI with every drag. I think the events shooting too frequencily and lag my game. – user1295050 Nov 07 '16 at 02:02
  • I don't know if my solution(s) dirty or clean. Hope I can find a clean solution. – user1295050 Nov 07 '16 at 02:22
  • it seems strange it would lag your game. i iwll try it when i get a chance. Did you try having a totally different camera for uI? that's often a good idea anyway. – Fattie Nov 07 '16 at 11:00
  • damn! it looks like Unity just does not allow "multiple physics raycaster systems". I'm glad you got some sort of solution; the solution I presented won't work. I'll keep thinking on it! – Fattie Nov 07 '16 at 16:19