- Home /
Detecting game object under UI
Hello,
I need to detect whether my game object is under a UI element or not (New UI, with a canvas. Not legacy UI). Is this possible, and if so, how could I achieve it?
I tried using ray casting, but then I learnt that ray casting doesn't work for UI elements (or so I think so).
Thanks!
Answer by AdmiralThrawn · Aug 13, 2017 at 08:38 AM
Hey mate,
one possible solution I can think of is to disable the Graphic Raycaster that you should have together with your Canvas object.
The steps you could try out:
Whenever a mouse click happens disable that raycaster object (have a reference to it)
Run your detection routine to check if a game object has been clicked (due to 1. it should now be detected)
If an object was hit, determine the xy-coordinates of your UI object. (Else, skip 3. to 5.)
Compare click-coordinates (in screen space) with xy-coordinates from 3.
Reenable the Graphic Raycaster in order to make your UI responsible again.
Let me know this helps.
Answer by wooolly · Aug 13, 2017 at 06:03 PM
Hey @AdmiralThrawn
I appreciate the response. However, I'm guessing this only works with the mouse? I don't actually want to use it for the mouse, I just need to know whether the GameObject was under the UI at any point during execution. Thanks though.
I ended up resolving my issue in the end by using a method I found online. I modified the method slightly to suit my own needs, and this is the method I'm using.
private bool IsPointInRT(Vector2 point, RectTransform rt)
{
// Get the rectangular bounding box of your UI element
Rect rect = rt.rect;
// Get the left, right, top, and bottom boundaries of the rect
float leftSide = rt.anchoredPosition.x;
// The below width is multiplied by 1.3f just to expand the width a slight bit, because it doesn't seem to measure properly (cuts short)
float rightSide = rt.anchoredPosition.x + (rect.width*1.3f);
float topSide = rt.anchoredPosition.y + rect.height;
float bottomSide = rt.anchoredPosition.y;
//Debug.Log(leftSide + ", " + rightSide + ", " + topSide + ", " + bottomSide);
// Check to see if the point is in the calculated bounds
if (point.x >= leftSide &&
point.x <= rightSide &&
point.y >= bottomSide &&
point.y <= topSide)
{
return true;
}
return false;
}
Note: Before deciding the use this method, I stumbled across RectTransformUtility.RectangleContainsScreenPoint - however, I tested that method provided by Unity and it didn't seem to work. I don't know whether I was using that method correctly or not, but it didn't seem to be returning very sensible results so I'd advise to all to use the method above instead (though you may need to change it slightly for your own needs, depending on how you use anchors etc). A link to the original method: https://stackoverflow.com/questions/40566250/unity-recttransform-contains-point
Nice! Following the $$anonymous$$ISS principle, the simple solution should always be the preferred choice! :)