I’m trying to make a 2d destructible terrain and i’m doing that by drawing on an image and using it with a 2d polygon collider. I found something online where i could draw at my mouse position and that worked fine. I tried to rewrite it a bit, so it would use the position of an other sprite instead of the mouses but i cant get it to work.
Any help would be greatly appreciated, here’s the code:
public SpriteRenderer _sr;
PolygonCollider2D _collider;
void Start()
{
_sr = GetComponent<SpriteRenderer>();
_collider = GetComponent<PolygonCollider2D>();
}
public void Destruct(Vector2 worldPos, float radius)
{
Vector2 hitPoint;
if (GetSpritePixelCoordsAtWorldPos(_sr, worldPos, out hitPoint))
{
DrawCircle(_sr.sprite.texture, Mathf.RoundToInt(hitPoint.x), Mathf.RoundToInt(hitPoint.y), (int)radius, new Color(255, 0, 0, 255));
Destroy(_collider);
_collider = gameObject.AddComponent<PolygonCollider2D>();
}
}
void DrawCircle(Texture2D tex, int cx, int cy, int r, Color col)
{
int x, y, px, nx, py, ny, d;
Color32[] tempArray = tex.GetPixels32();
for (x = 0; x <= r; x++)
{
d = (int)Mathf.Ceil(Mathf.Sqrt(r * r - x * x));
for (y = 0; y <= d; y++)
{
px = cx + x;
nx = cx - x;
py = cy + y;
ny = cy - y;
if (tempArray.Length > py * tex.width + px)
tempArray[py * tex.width + px] = col;
if (tempArray.Length > py * tex.width + nx)
tempArray[py * tex.width + nx] = col;
if (tempArray.Length > ny * tex.width + px)
tempArray[ny * tex.width + px] = col;
if (tempArray.Length > ny * tex.width + nx)
tempArray[ny * tex.width + nx] = col;
}
}
tex.SetPixels32(tempArray);
tex.Apply();
}
public bool GetSpritePixelCoordsAtWorldPos(SpriteRenderer spriteRenderer, Vector2 orgPos, out Vector2 vec)
{
vec = Vector2.zero;
Vector3 dir = new Vector3(orgPos.y, orgPos.y, 5F);
Ray ray = new Ray(dir, new Vector3(0, 0, -1F));
return getTexPos(spriteRenderer, ray, out vec);
}
bool getTexPos(SpriteRenderer spriteRenderer, Ray ray, out Vector2 vec)
{
vec = Vector2.zero;
if (spriteRenderer == null) return false;
Sprite sprite = spriteRenderer.sprite;
if (sprite == null) return false;
Texture2D texture = sprite.texture;
if (texture == null) return false;
// Check atlas packing mode
if (sprite.packed && sprite.packingMode == SpritePackingMode.Tight)
{
// Cannot use textureRect on tightly packed sprites
Debug.LogError("SpritePackingMode.Tight atlas packing is not supported!");
// TODO: support tightly packed sprites
return false;
}
// Craete a plane so it has the same orientation as the sprite transform
Plane plane = new Plane(transform.forward, transform.position);
// Intersect the ray and the plane
float rayIntersectDist; // the distance from the ray origin to the intersection point
if (!plane.Raycast(ray, out rayIntersectDist)) return false; // no intersection
// Convert world position to sprite position
// worldToLocalMatrix.MultiplyPoint3x4 returns a value from based on the texture dimensions (+/- half texDimension / pixelsPerUnit) )
// 0, 0 corresponds to the center of the TEXTURE ITSELF, not the center of the trimmed sprite textureRect
Vector3 spritePos = spriteRenderer.worldToLocalMatrix.MultiplyPoint3x4(ray.origin + (ray.direction * rayIntersectDist));
Rect textureRect = sprite.textureRect;
float pixelsPerUnit = sprite.pixelsPerUnit;
float halfRealTexWidth = texture.width * 0.5f; // use the real texture width here because center is based on this -- probably won't work right for atlases
float halfRealTexHeight = texture.height * 0.5f;
// Convert to pixel position, offsetting so 0,0 is in lower left instead of center
int texPosX = (int)(spritePos.x * pixelsPerUnit + halfRealTexWidth);
int texPosY = (int)(spritePos.y * pixelsPerUnit + halfRealTexHeight);
// Check if pixel is within texture
if (texPosX < 0 || texPosX < textureRect.x || texPosX >= Mathf.FloorToInt(textureRect.xMax)) return false; // out of bounds
if (texPosY < 0 || texPosY < textureRect.y || texPosY >= Mathf.FloorToInt(textureRect.yMax)) return false; // out of bounds
vec = new Vector2(texPosX, texPosY);
return true;
}