- Home /
New UI - Ignore raycast where alpha is 0
So new UI, I have a frame for a panel, and I want the frame to block clicks to components behind it. Of course, the center of the frame is transparent, and contains the contents of the window. The clicks in the transparent area should not be blocked.
Seems obvious, but found no solution in unity. Canvas group component (for UI elements) and IsPointerOverGameObject() (for game objects) do not take alpha into account and will cause the entire inside of the frame to be blocked as well...
(Edit: See image below. Green area should pass clicks through to components below, while red area should block)
Ideas?
I think best option is to create 2 types of images, which can pass ray, and can't, then just palce them and everything will be okey.
Splitting the image into four parts is always an option if everything else fails. It's probably the easiest way of doing things, but it's a bit annoying.
Perhaps you can put an invisible component above the UI that covers the green area. This component would intercept raycasts that would originally hit the transparent pixels of the red image and pass those raycasts to the area behind.
Answer by RafiXWPT · Aug 27, 2015 at 05:26 PM
Just for that "transparent" area use stand alone panel and add script where you will be checking alpha:
if(yourobject.getComponent<CanvasGroup>().alpha == 0f)
yourobject.getComponent<CanvasGroup>().blockRaycast = false;
else
yourobject.getComponent<CanvasGroup>().blockRaycast = true;
Please check if my spelling is correct cus its from memory ;)
That's not what I meant, the alpha of the canvas group is constant. I need the image to block clicks to elements behind it only in the areas where the image is not transparent, ins$$anonymous$$d of the entire area of the image.
Yes it is, and that is the question, seems like something other people might have tried to do as well...
I can't see any good UI method if you won't separate that onto different objects, you have to hardcode GetPixels, method and check alpha there.
Answer by seguso · Apr 15, 2017 at 08:14 AM
Here is the solution: use RaycastAll to retrieve all the objects hit, then return the closest object such that the alpha value of the pixel is not 0.
private static RaycastHit? RaycastWithTransparency(Ray ray)
{
var res = Physics.RaycastAll(ray, float.MaxValue).ToList().OrderBy(h => h.distance);
foreach (var h in res)
{
var col = h.collider;
Renderer rend = h.transform.GetComponent<Renderer>();
Texture2D tex = rend.material.mainTexture as Texture2D;
var xInTex = (int) (h.textureCoord.x*tex.width);
var yInTex = (int) (h.textureCoord.y*tex.height);
var pix = tex.GetPixel(xInTex, yInTex);
if (pix.a > 0)
{
//Debug.Log("You hit: " + col.name + " position " + h.textureCoord.x + " , " + h.textureCoord.y);
return h;
}
}
return null;
}
Your answer
Follow this Question
Related Questions
Transparent Images as UI 0 Answers
OnPointerEnter and OnPointerExit not being triggered 0 Answers
How i set image from Raycast hit target object? 2 Answers
Check if UI element is fully inside another UI element 1 Answer
Buttons become invisible when changing color (on Button or on Image) in script -1 Answers