How to get the alpha-cropped bounds of a Sprite?

Is there a way to get the alpha-cropped bounds of a Sprite? I’m trying to make an object selectable which shows a sprite animation, and the sprite size changes a lot, so I’m trying to get the dynamic bounds of the currently displayed frame and I can’t use a static rect/collider for this.

I expected to get the bounds in spriteRenderer.bounds or spriteRenderer.sprite.bounds but both return the size of the original sprite, and not the actual visible area of the mesh. Also, there is no access to the displayed mesh (in tight and rect mode). I tried to calculate the bounds with the exposed properties of Sprite, but I couldn’t find a way to move the rect to the right place. Also, there’s no way to get the pixelsPerUnit of a sprite to do this (although this is no problem in my case because all the relevant sprites have the same pixelPerUnit size).

 Rect croppedRect = new Rect(
spriteRenderer.sprite.textureRectOffset.x / pixelsPerUnit,
spriteRenderer.sprite.textureRectOffset.y / pixelsPerUnit,
spriteRenderer.sprite.textureRect.width / pixelsPerUnit,
spriteRenderer.sprite.textureRect.height / pixelsPerUnit);

Vector3 pMin = spriteRenderer.transform.TransformPoint( croppedRect.min );
Vector3 pMax = spriteRenderer.transform.TransformPoint(croppedRect.max );

This is how I tried it. The size is right, but the positioning is completely wrong. I don’t really understand what the textureRectOffset property means, in my tests it was always the same like textureRect.x and y.

1 Like

Ok, right after a few hours of not finding the solution, I found a part of the solution 5 minutes after posting the question:

        Rect croppedRect = new Rect(
            (spriteRenderer.sprite.textureRectOffset.x - spriteRenderer.sprite.rect.width/2f) / pixelsPerUnit,
            (spriteRenderer.sprite.textureRectOffset.y - spriteRenderer.sprite.rect.height/2f) / pixelsPerUnit,
            spriteRenderer.sprite.textureRect.width / pixelsPerUnit,
            spriteRenderer.sprite.textureRect.height / pixelsPerUnit);

        Vector3 pMin = spriteRenderer.transform.TransformPoint(croppedRect.min);
        Vector3 pMax = spriteRenderer.transform.TransformPoint(croppedRect.max );

This works with rect packed and with unpacked, but still not with tightly packed Sprites. In the previous post I forgot to mention that the main problem was to find a solution that works in the (unpacked) editor as well as in a (tightly packed) build.

It would still be nice to have a possiblity to find the bounds of a tightly packed sprite. And/or access to the pixelsPerUnity of a sprite.

1 Like

I’ve seen that access to pixelsPerUnit is now possible in 4.6b20, which is great and makes the approach above more reusable.

But I still haven’t found a way to get the bounds/rect of tightly packed sprites…

Hi any_user,

“I still haven’t found a way to get the bounds/rect of tightly packed sprites…”

I wanted to look into this and see If I can find you a solution. Before I do so; I wanted to know if you had found your own solution in the time you have been waiting for an answer from the community.

Let me know.

I finally found the UnityEngine.Sprites.DataUtility.GetPadding() function which gives you exactly the cropping information (in pixels) needed, for both types of packing. I’m pretty sure DataUtility didn’t have this function when I first tried it.

With the access to the pivot of a sprite (introduced in a Unity 5 beta I think), it was possible to get the cropped bounds in all cases I tested. Before Unity 5 you could either save the pivot position somewhere else or it will only work with a predefined value.

6 Likes

I know i’m late to the party, but was looking into similar issue and saw this thread.
Was trying to get it to work using your codes and after much experimenting, finally found the solution
Hope this can be helpful to someone~

// texture rect's center
        Rect croppedRect = new Rect(
            (sprite.textureRectOffset.x + sprite.textureRect.width / 2f) / sprite.pixelsPerUnit,
            (sprite.textureRectOffset.y + sprite.textureRect.height / 2f) / sprite.pixelsPerUnit,
            sprite.textureRect.width / sprite.pixelsPerUnit,
            sprite.textureRect.height / sprite.pixelsPerUnit);
       
        // offset is relative to sprite's pivot
        collider.offset = croppedRect.position - sprite.pivot / sprite.pixelsPerUnit;
        collider.size = croppedRect.size;
6 Likes