Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- public class DrawWithMouse : MonoBehaviour {
- public bool erase = false;
- public float radius = 50f;
- public SpriteRenderer sr;
- void Update () {
- if(Input.GetMouseButton(0))
- {
- Vector2 mousePos;
- if(GetSpritePixelColorUnderMousePointer(sr, out mousePos))
- {
- Circle(sr.sprite.texture, Mathf.RoundToInt(mousePos.x), Mathf.RoundToInt(mousePos.y), Mathf.RoundToInt(radius), erase ? new Color(0, 0, 0, 0) : Color.black);
- }
- }
- }
- void Circle(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++)
- {
- if (x < tex.width && y < tex.height)
- {
- px = cx + x;
- nx = cx - x;
- py = cy + y;
- ny = cy - y;
- tempArray[py * tex.width + px] = col;
- tempArray[py * tex.width + nx] = col;
- tempArray[ny * tex.width + px] = col;
- tempArray[ny * tex.width + nx] = col;
- }
- }
- }
- tex.SetPixels32(tempArray);
- tex.Apply();
- }
- Vector2 MousePosToSpriteCoords()
- {
- var pixelWidth = sr.sprite.rect.width;
- var pixelHeight = sr.sprite.rect.height;
- var unitsToPixels = pixelWidth / sr.bounds.size.x * transform.localScale.x;
- var pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
- pos.z = transform.position.z;
- pos = transform.InverseTransformPoint(pos);
- int xPixel = Mathf.RoundToInt(pos.x * unitsToPixels);
- int yPixel = Mathf.RoundToInt(pos.y * unitsToPixels);
- Color32 color32 = sr.sprite.texture.GetPixel(xPixel, yPixel);
- //Debug.Log("(" + xPixel + ", " + yPixel + ") " + color32);
- return new Vector2((xPixel), (xPixel));
- }
- public bool GetSpritePixelColorUnderMousePointer(SpriteRenderer spriteRenderer, out Vector2 vec)
- {
- vec = Vector2.zero;
- Camera cam = Camera.main;
- Vector2 mousePos = Input.mousePosition;
- Vector2 viewportPos = cam.ScreenToViewportPoint(mousePos);
- if (viewportPos.x < 0.0f || viewportPos.x > 1.0f || viewportPos.y < 0.0f || viewportPos.y > 1.0f) return false; // out of viewport bounds
- // Cast a ray from viewport point into world
- Ray ray = cam.ViewportPointToRay(viewportPos);
- // Check for intersection with sprite and get the color
- return getTextPos(spriteRenderer, ray, out vec);
- }
- private bool IntersectsSprite(SpriteRenderer spriteRenderer, Ray ray, out Color color)
- {
- color = new Color();
- 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
- // Get pixel color
- color = texture.GetPixel(texPosX, texPosY);
- return true;
- }
- bool getTextPos(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;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement