Corners of SpriteRenderer at any position

I’m wanting to draw a GUI.Rect around a 2D sprite. The purpose is a simple UI selection box when the object is clicked. I’ve found my way to a working solution:

  1. Use the SpriteRenderer’s center and extents to locate the top left corner.
  2. Use the same to find the bottom right corner.
  3. Finding the difference between the two to arrive at a height and width.
  4. Drawing the rect with the top left vector + height and width.

Here’s the code (omitting a Camera.main conversion from world to screen space for the purposes of the Rect) —

Vector3 topLeft_worldSpace = new Vector3(spriteRenderer.bounds.center.x - spriteRenderer.bounds.extents.x, -spriteRenderer.bounds.center.y - spriteRenderer.bounds.extents.y, 0);
          
Vector3 bottomRight_worldSpace = new Vector3(spriteRenderer.bounds.center.x + spriteRenderer.bounds.extents.x, spriteRenderer.bounds.center.y + spriteRenderer.bounds.extents.y, 0);
          
Vector3 size = bottomRight_screenSpace - topLeft_screenSpace;

Rect rect = new Rect(topLeft_screenSpace.x, topLeft_screenSpace.y, size.x, size.y);

And it works! Until…

When I move my sprite in world space, the rect goes completely haywire. It moves around world space as the sprite moves about.

I suspect the issue is the sprite’s rotation is not being accounted for, but that’s only a hunch.

(In the image below, my Rect has suddenly stretched very tall. Other times, it’s very small, or very wide. In other words, I’m using completely the wrong values!)

Any advice on how best to achieve this? I promise before posting this, I’ve spent days fiddling. I’m just missing something.

7623043--948124--Screen Shot 2021-11-02 at 9.10.06 AM.png

Lines 1 and 3 define some world-space axis-aligned bounds. Lines 5 and 7 refer to something else i.e. some screenSpace thing.

You use Camera.WorldToScreenPoint to convert world-space to screen-space.

Also note that there’s Bounds.min/max which will calculate the extents of the bounds for you.

I pulled out some of my code for brevity, but yes, I am converting world space to screen space with Camera.main correctly. So I can rule that out. I’ll take a look at Bounds.min/max, though. Thank you.

Just need to debug it then. Try drawing the world-space bounds using a Box first to ensure it’s what you expect or just output to the console. Garbage In → Garbage Out and all that!

That’s been my past few days - debugging. :slight_smile: That’s why I finally came here. But I’ll head back to the drawing boards once more.

So you have verified that the renderer bounds is correct then?

In case someone comes across this thread one day and does not find the above exchange helpful, here’s what I missed:

Per Unity - Scripting API: GUIUtility.GUIToScreenPoint

Note: In Unity the screen space y coordinate varies from zero at the top edge of the window to a maximum at the bottom edge of the window. This is different from what you might expect.

While I was correctly converting from world space to screen space, my rect was “running away” from my object because my y coordinates were exactly reversed. I had to use GUIToScreenPoint additionally, and then draw my Rect setting the y coordinate to:

Screen.height - guiPosition.y

Phew!

Happy building everyone.

2 Likes