Advertisement
Guest User

Untitled

a guest
Sep 25th, 2017
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 8.37 KB | None | 0 0
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4.  
  5. public class DrawWithMouse : MonoBehaviour {
  6.  
  7.     public bool erase = false;
  8.     public float radius = 50f;
  9.  
  10.     public SpriteRenderer sr;
  11.  
  12.  
  13.     void Update () {
  14.  
  15.         if(Input.GetMouseButton(0))
  16.         {
  17.             Vector2 mousePos;
  18.             if(GetSpritePixelColorUnderMousePointer(sr, out mousePos))
  19.             {
  20.                 Circle(sr.sprite.texture, Mathf.RoundToInt(mousePos.x), Mathf.RoundToInt(mousePos.y), Mathf.RoundToInt(radius), erase ? new Color(0, 0, 0, 0) : Color.black);
  21.             }
  22.         }  
  23.     }
  24.  
  25.  
  26.     void Circle(Texture2D tex, int cx, int cy, int r, Color col)
  27.     {
  28.         int x, y, px, nx, py, ny, d;
  29.         Color32[] tempArray = tex.GetPixels32();
  30.  
  31.         for (x = 0; x <= r; x++)
  32.         {
  33.             d = (int)Mathf.Ceil(Mathf.Sqrt(r * r - x * x));
  34.             for (y = 0; y <= d; y++)
  35.             {
  36.                 if (x < tex.width && y < tex.height)
  37.                 {
  38.                     px = cx + x;
  39.                     nx = cx - x;
  40.                     py = cy + y;
  41.                     ny = cy - y;
  42.  
  43.                     tempArray[py * tex.width + px] = col;
  44.                     tempArray[py * tex.width + nx] = col;
  45.                     tempArray[ny * tex.width + px] = col;
  46.                     tempArray[ny * tex.width + nx] = col;
  47.                 }
  48.             }
  49.         }
  50.         tex.SetPixels32(tempArray);
  51.         tex.Apply();
  52.     }
  53.  
  54.     Vector2 MousePosToSpriteCoords()
  55.     {
  56.         var pixelWidth = sr.sprite.rect.width;
  57.         var pixelHeight = sr.sprite.rect.height;
  58.         var unitsToPixels = pixelWidth / sr.bounds.size.x * transform.localScale.x;
  59.  
  60.         var pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
  61.         pos.z = transform.position.z;
  62.         pos = transform.InverseTransformPoint(pos);
  63.  
  64.         int xPixel = Mathf.RoundToInt(pos.x * unitsToPixels);
  65.         int yPixel = Mathf.RoundToInt(pos.y * unitsToPixels);
  66.  
  67.         Color32 color32 = sr.sprite.texture.GetPixel(xPixel, yPixel);
  68.         //Debug.Log("(" + xPixel + ", " + yPixel + ")  " + color32);
  69.  
  70.         return new Vector2((xPixel), (xPixel));
  71.     }
  72.  
  73.     public bool GetSpritePixelColorUnderMousePointer(SpriteRenderer spriteRenderer, out Vector2 vec)
  74.     {
  75.         vec = Vector2.zero;
  76.  
  77.         Camera cam = Camera.main;
  78.         Vector2 mousePos = Input.mousePosition;
  79.         Vector2 viewportPos = cam.ScreenToViewportPoint(mousePos);
  80.         if (viewportPos.x < 0.0f || viewportPos.x > 1.0f || viewportPos.y < 0.0f || viewportPos.y > 1.0f) return false; // out of viewport bounds
  81.                                                                                                                         // Cast a ray from viewport point into world
  82.         Ray ray = cam.ViewportPointToRay(viewportPos);
  83.  
  84.         // Check for intersection with sprite and get the color
  85.         return getTextPos(spriteRenderer, ray, out vec);
  86.     }
  87.     private bool IntersectsSprite(SpriteRenderer spriteRenderer, Ray ray, out Color color)
  88.     {
  89.         color = new Color();
  90.         if (spriteRenderer == null) return false;
  91.         Sprite sprite = spriteRenderer.sprite;
  92.         if (sprite == null) return false;
  93.         Texture2D texture = sprite.texture;
  94.         if (texture == null) return false;
  95.         // Check atlas packing mode
  96.         if (sprite.packed && sprite.packingMode == SpritePackingMode.Tight)
  97.         {
  98.             // Cannot use textureRect on tightly packed sprites
  99.             Debug.LogError("SpritePackingMode.Tight atlas packing is not supported!");
  100.             // TODO: support tightly packed sprites
  101.             return false;
  102.         }
  103.         // Craete a plane so it has the same orientation as the sprite transform
  104.         Plane plane = new Plane(transform.forward, transform.position);
  105.         // Intersect the ray and the plane
  106.         float rayIntersectDist; // the distance from the ray origin to the intersection point
  107.         if (!plane.Raycast(ray, out rayIntersectDist)) return false; // no intersection
  108.                                                                      // Convert world position to sprite position
  109.                                                                      // worldToLocalMatrix.MultiplyPoint3x4 returns a value from based on the texture dimensions (+/- half texDimension / pixelsPerUnit) )
  110.                                                                      // 0, 0 corresponds to the center of the TEXTURE ITSELF, not the center of the trimmed sprite textureRect
  111.         Vector3 spritePos = spriteRenderer.worldToLocalMatrix.MultiplyPoint3x4(ray.origin + (ray.direction * rayIntersectDist));
  112.         Rect textureRect = sprite.textureRect;
  113.         float pixelsPerUnit = sprite.pixelsPerUnit;
  114.         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
  115.         float halfRealTexHeight = texture.height * 0.5f;
  116.         // Convert to pixel position, offsetting so 0,0 is in lower left instead of center
  117.         int texPosX = (int)(spritePos.x * pixelsPerUnit + halfRealTexWidth);
  118.         int texPosY = (int)(spritePos.y * pixelsPerUnit + halfRealTexHeight);
  119.         // Check if pixel is within texture
  120.         if (texPosX < 0 || texPosX < textureRect.x || texPosX >= Mathf.FloorToInt(textureRect.xMax)) return false; // out of bounds
  121.         if (texPosY < 0 || texPosY < textureRect.y || texPosY >= Mathf.FloorToInt(textureRect.yMax)) return false; // out of bounds
  122.                                                                                                                    // Get pixel color
  123.         color = texture.GetPixel(texPosX, texPosY);
  124.         return true;
  125.     }
  126.  
  127.     bool getTextPos(SpriteRenderer spriteRenderer, Ray ray, out Vector2 vec)
  128.     {
  129.         vec = Vector2.zero;
  130.  
  131.         if (spriteRenderer == null) return false;
  132.         Sprite sprite = spriteRenderer.sprite;
  133.         if (sprite == null) return false;
  134.         Texture2D texture = sprite.texture;
  135.         if (texture == null) return false;
  136.         // Check atlas packing mode
  137.         if (sprite.packed && sprite.packingMode == SpritePackingMode.Tight)
  138.         {
  139.             // Cannot use textureRect on tightly packed sprites
  140.             Debug.LogError("SpritePackingMode.Tight atlas packing is not supported!");
  141.             // TODO: support tightly packed sprites
  142.             return false;
  143.         }
  144.         // Craete a plane so it has the same orientation as the sprite transform
  145.         Plane plane = new Plane(transform.forward, transform.position);
  146.         // Intersect the ray and the plane
  147.         float rayIntersectDist; // the distance from the ray origin to the intersection point
  148.         if (!plane.Raycast(ray, out rayIntersectDist)) return false; // no intersection
  149.                                                                      // Convert world position to sprite position
  150.                                                                      // worldToLocalMatrix.MultiplyPoint3x4 returns a value from based on the texture dimensions (+/- half texDimension / pixelsPerUnit) )
  151.                                                                      // 0, 0 corresponds to the center of the TEXTURE ITSELF, not the center of the trimmed sprite textureRect
  152.         Vector3 spritePos = spriteRenderer.worldToLocalMatrix.MultiplyPoint3x4(ray.origin + (ray.direction * rayIntersectDist));
  153.         Rect textureRect = sprite.textureRect;
  154.         float pixelsPerUnit = sprite.pixelsPerUnit;
  155.         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
  156.         float halfRealTexHeight = texture.height * 0.5f;
  157.         // Convert to pixel position, offsetting so 0,0 is in lower left instead of center
  158.         int texPosX = (int)(spritePos.x * pixelsPerUnit + halfRealTexWidth);
  159.         int texPosY = (int)(spritePos.y * pixelsPerUnit + halfRealTexHeight);
  160.  
  161.         // Check if pixel is within texture
  162.         if (texPosX < 0 || texPosX < textureRect.x || texPosX >= Mathf.FloorToInt(textureRect.xMax)) return false; // out of bounds
  163.         if (texPosY < 0 || texPosY < textureRect.y || texPosY >= Mathf.FloorToInt(textureRect.yMax)) return false; // out of bounds
  164.  
  165.         vec = new Vector2(texPosX, texPosY);
  166.  
  167.         return true;
  168.     }
  169. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement