- Home /
Unity 4.6 UI - Ignore raycast
Is there way to tell the UI event system to ignore a UI gameObject when doing raycasts? I have transparent panels that I want the clicks to go through.
Canvas
|- Panel1
|- Button1
|- Panel2
|- Button2
+-------------------+
| +-----------------------+
| | | |
| | [Button1] | |
+-------|-----------+ [Button2] |
+-----------------------+
Panel2 covers Panel1 but I want the clicks to go through so button1 may be pressed.
Answer by troien · Nov 10, 2014 at 10:51 AM
Yes, add a Canvas Group component and uncheck the 'Blocks Raycasts' checkbox. (You'll probably want to unckeck the 'Interactable' checkbox aswell)
ps. You can use this Component aswell to do your fading using the 'Alpha' slider.
It almost worked. I've updated my question to illustrate the problem. If I uncheck "Blocks Raycasts" on Panel2 I can no longer click on Button2 as it seems to affect all the children as well. I've tried adding a CanvasGroup to Button2 as well and tried different settings but nothing works.
I might have found a working solution. If I disable the Image-component from Panel2 the clicks seems to go through.
Hmmm... This looks like a bug of the 'Ignore Parent Groups' chekbox. Because it doesn't ignore the parent group (Only the value of Alpha) if you check it...
I did find a kind of hacky way to work around this, which is implementing your own ICanvasRaycastFilter.
This piece of code can be added to your panels (ins$$anonymous$$d of the Canvas Group)
using UnityEngine;
public class CustomRaycastFilter : $$anonymous$$onoBehaviour, ICanvasRaycastFilter
{
public Raycast$$anonymous$$ode mode;
public enum Raycast$$anonymous$$ode
{
ReceiveNone, // You can't interact with us or any of our children
ReceiveAll, // You can interact with us and all of our children
OnlyChildsReceive // You can't interact with us, but you can with any of our children
}
public bool IsRaycastLocationValid(Vector2 sp, Camera eventCamera)
{
switch (mode)
{
case Raycast$$anonymous$$ode.ReceiveNone:
return false;
case Raycast$$anonymous$$ode.ReceiveAll:
RectTransform rt = transform as RectTransform;
Vector2 localPos = rt.worldToLocal$$anonymous$$atrix.$$anonymous$$ultiplyPoint(sp);
return rt.rect.Contains(localPos);
case Raycast$$anonymous$$ode.OnlyChildsReceive:
for (int i = 0; i < transform.childCount; i++)
{
RectTransform childRect = transform.GetChild(i) as RectTransform;
Vector2 childPos = childRect.worldToLocal$$anonymous$$atrix.$$anonymous$$ultiplyPoint(sp);
if (childRect.rect.Contains(childPos))
{
return true;
}
}
return false;
default:
throw new System.NotImplementedException("$$anonymous$$ode not implemented");
}
}
}
Though a better solution might be to simply change your hierarchy to something like this:
Canvas
|- Container1
|- Panel1
|- Button1
|- Container2
|- Panel2
|- Button2
$$anonymous$$eeping the Canvas Group component on the panel. The Containers are empty GameObjects with no Components (Other than RectTransform). Their size is equal to the old panels, and the new panels size simply fill the containers size.
Yes, it was a bug, should be fixed in 4.6.2