I want to select 2D sprites with the mouse.
I use box colliders and Physics2D.OverlapPointAll(); to do this.
I also want to ignore clicks on the fully transparent parts of the sprite inside the box collider.
I am trying to accomplish this by using Texture2D.GetPixelBilinear to identify transparent pixels (alpha = 0), but It’s not working and I don’t understand why.
No matter where I click in any box collider it always returns a Color with an alpha of 0. I tried hardcoding the GetPixelBilinear() inputs to specific values but never got an alpha value that wasn’t 0.
My code is listed below in the GameManager. All sprites in testing have box colliders and are read/write enabled.
void Update()
{
SpriteSelection();
}
void SpriteSelection()
{
// When mouse 0 is pressed
if (Input.GetMouseButton(0))
{
Vector2 pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
Collider2D[] collidersHit = Physics2D.OverlapPointAll(pos);
GameObject selectedObject = null;
for (int ii = 0; ii < collidersHit.Length; ii++)
{
Sprite sprite = collidersHit[ii].gameObject.GetComponent<SpriteRenderer>().sprite;
Color pixel = sprite.texture.GetPixelBilinear(pos.x, pos.y);
Debug.Log(pixel.ToString());
}
}
}
Alright, came up with a solution that lets me select the colour of a pixel in any sprite with a collider no matter where it is in the world, no matter what its PixelsPerUnit is, and no matter the location of sprite on original texture (for textures that are sprite mode: multiple)
Posting it here just in case anyone else has use of it.
void SpriteSelection()
{
// When mouse 0 is pressed
if (Input.GetMouseButton(0))
{
Vector2 pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
Collider2D[] collidersHit = Physics2D.OverlapPointAll(pos);
GameObject selectedObject = null;
for (int ii = 0; ii < collidersHit.Length; ii++)
{
GameObject gameObject = collidersHit[ii].gameObject;
Sprite sprite = gameObject.GetComponent<SpriteRenderer>().sprite;
Rect rect = sprite.textureRect;
// calculate the distance of the mouse from the center of the sprite's transform
float x = pos.x - gameObject.transform.position.x;
float y = pos.y - gameObject.transform.position.y;
// convert the x and y values from units to pixels
x *= sprite.pixelsPerUnit;
y *= sprite.pixelsPerUnit;
// modify so pixel distance from bottom left corner instead of from center
x += rect.width / 2;
y += rect.height /2;
// adjust for location of sprite on original texture
x += rect.x;
y += rect.y;
// mouse position x and y subtract transform position x and y, then multiply by pixels per unit
Color pixel = sprite.texture.GetPixel(Mathf.FloorToInt(x), Mathf.FloorToInt(y));
Debug.Log(pixel.ToString());
}
}
}