Skip to content

Commit 5ca65ec

Browse files
authored
Merge pull request UnityCommunity#49 from pkunjam/master
Get sprite color in realtime
2 parents 2224efe + 315c041 commit 5ca65ec

File tree

1 file changed

+78
-0
lines changed

1 file changed

+78
-0
lines changed
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
using UnityEngine;
5+
6+
// This script gets the color of a sprite in realtime
7+
// Usage: Attach this script to any gameobject having a sprite renderer component
8+
9+
public class SpriteColor : MonoBehaviour
10+
{
11+
public static Color GetColor { get; set; }
12+
13+
public SpriteRenderer targetSprite;
14+
15+
Color finalColor;
16+
17+
void Update()
18+
{
19+
GetSpritePixelColorUnderMousePointer(targetSprite, out finalColor);
20+
}
21+
22+
public bool GetSpritePixelColorUnderMousePointer(SpriteRenderer spriteRenderer, out Color color)
23+
{
24+
color = new Color();
25+
Camera cam = Camera.main;
26+
Vector2 mousePos = Input.mousePosition;
27+
Vector2 viewportPos = cam.ScreenToViewportPoint(mousePos);
28+
if (viewportPos.x < 0.0f || viewportPos.x > 1.0f || viewportPos.y < 0.0f || viewportPos.y > 1.0f) return false; // out of viewport bounds
29+
30+
// Cast a ray from viewport point into world
31+
Ray ray = cam.ViewportPointToRay(viewportPos);
32+
33+
// Check for intersection with sprite and get the color
34+
return IntersectsSprite(spriteRenderer, ray, out color);
35+
}
36+
37+
private bool IntersectsSprite(SpriteRenderer spriteRenderer, Ray ray, out Color color)
38+
{
39+
color = new Color();
40+
if (spriteRenderer == null) return false;
41+
42+
Sprite sprite = spriteRenderer.sprite;
43+
if (sprite == null) return false;
44+
45+
Texture2D texture = sprite.texture;
46+
if (texture == null) return false;
47+
48+
49+
// Craete a plane so it has the same orientation as the sprite transform
50+
Plane plane = new Plane(transform.forward, transform.position);
51+
52+
// Intersect the ray and the plane
53+
float rayIntersectDist; // the distance from the ray origin to the intersection point
54+
if (!plane.Raycast(ray, out rayIntersectDist)) return false;
55+
56+
// Convert world position to sprite position
57+
// worldToLocalMatrix.MultiplyPoint3x4 returns a value from based on the texture dimensions (+/- half texDimension / pixelsPerUnit) )
58+
// 0, 0 corresponds to the center of the TEXTURE ITSELF, not the center of the trimmed sprite textureRect
59+
60+
Vector3 spritePos = spriteRenderer.worldToLocalMatrix.MultiplyPoint3x4(ray.origin + (ray.direction * rayIntersectDist));
61+
Rect textureRect = sprite.textureRect;
62+
float pixelsPerUnit = sprite.pixelsPerUnit;
63+
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
64+
float halfRealTexHeight = texture.height * 0.5f;
65+
// Convert to pixel position, offsetting so 0,0 is in lower left instead of center
66+
int texPosX = (int)(spritePos.x * pixelsPerUnit + halfRealTexWidth);
67+
int texPosY = (int)(spritePos.y * pixelsPerUnit + halfRealTexHeight);
68+
// Check if pixel is within texture
69+
if (texPosX < 0 || texPosX < textureRect.x || texPosX >= Mathf.FloorToInt(textureRect.xMax)) return false; // out of bounds
70+
if (texPosY < 0 || texPosY < textureRect.y || texPosY >= Mathf.FloorToInt(textureRect.yMax)) return false; // out of bounds
71+
// Get pixel color
72+
color = texture.GetPixel(texPosX, texPosY);
73+
GetColor = color;
74+
75+
return true;
76+
}
77+
78+
}

0 commit comments

Comments
 (0)