I have this UI element that follows an arrow around the screen. The problem is that sometimes, due to the parenting, the element goes outside the screen. I need a way for it to "hit the walls of the screen" and don't move beyond that point. This is made trickier by the fact that the UI element is animated, and "pops out" onto the screen.

I've tried several solutions and the best so far has only made it so that the pivot point does not go beyond the screen edge. I know I somehow have to calculate a bounding rect for the UI element, and then Clamp() its edges in screen space, but I honestly have no idea how to do this in code.

  • \$\begingroup\$ Can we see your current code? This is made harder by not knowing how your already implementing the half-working collision. \$\endgroup\$ – Gnemlock Aug 13 '16 at 22:52

All you need to do is to adjust the clamping with the size of the object. Use the width and height properties of the UI elements's RectTransform (I've never actually done any Unity programming, so these might be referencing some old obsolete patterns, but I'm sure you could find out how to translate the code to use some other implementation).

Once you have your size, you need to convert it to the screen space (as you need to do for your object's origin), using something like RectTransformUtility.WorldToScreenPoint (Again, could be an obsolete method or a better alternative available out there).

Finally, you need the viewport size, probably from Screen.Width/Height. Once you have those, all that's left to do is to perform the actual clamping. We need to make sure that all the corners of the UI element are inside the viewport. So, we perform a clamping in the screen space, and finally convert the position back to world space and apply it back to the UI element (I'm not 100% sure about which space UI elements lie in by default, so I'll assume that they use world space coordinates).

origin.x = clamp(origin.x, objectWidth / 2.0, Screen.Width - objectWidth / 2.0);
origin.y = clamp(origin.y, objectHeight / 2.0, Screen.Height - objectHeight / 2.0);

The code above limits the origin to lie within the screen bounds with the object size taken into account. The origin has to be atleast one object half size away from the top-left of the screen (objectWidth / 2.0, objectHeight / 2.0), and it can't exceed the screen size by the same amount.

  • 2
    \$\begingroup\$ you see the thing is that this UI element has a scale animation to make it pop out when needed. So I dont think your solution works. I forgot to mention this is the actual question; \$\endgroup\$ – Uri Popov Aug 9 '16 at 9:35
  • \$\begingroup\$ Can you not fetch the scale from the object? And in future, please add the information that invalidates some answers to the question in time. \$\endgroup\$ – Tyyppi_77 Aug 9 '16 at 10:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.