- Home /
Get the color under the mouse cursor
Hello there!
Getting the color of a pixel on a 3d object is pretty easy, but anyone knows how to do the same thing on the GUI? What I need is a color picker tool.
Thanks!
Answer by tylo · Nov 07, 2011 at 07:09 AM
There is a thread about this on the Unity forums that has a clever solution. I'm actually trying to implement it myself right now.
For some reason, though, the GetPixel method keeps returning a value I'm not expecting.
Ok, here is the solution I use. First, you need to get yourself any color picking texture. I used this one. Now, for some reason the closer I would get to "Black" the brighter the color would get. So my solution was to display one texture and read a color from another that was flipped. You drag these two textures into the ColorPicker
inspector's respective slots.
First, I've altered this code file from the above form thread which includes a delegate and event system so that the actual setting of the color can be done outside of this class:
using UnityEngine;
using System;
using System.Collections;
using System.Runtime.CompilerServices;
public class ColorPicker : MonoBehaviour {
public Texture2D colorPicker;
public Texture2D colorPickerFlipped;
public int ImageWidth = 256;
public int ImageHeight = 256;
public delegate void OnColorPickedHandler(Color c);
private OnColorPickedHandler m_onColorPickedEvent= delegate{ };
private static ColorPicker instance;
public static ColorPicker Instance{
get{
if (instance == null)
instance = new GameObject ("ColorPicker").AddComponent<ColorPicker> ();
return instance;
}
}
public static event OnColorPickedHandler OnColorPickedEvent
{
[MethodImpl(MethodImplOptions.Synchronized)]
add
{
Instance.m_onColorPickedEvent -= value;
Instance.m_onColorPickedEvent += value;
}
[MethodImpl(MethodImplOptions.Synchronized)]
remove
{
Instance.m_onColorPickedEvent -= value;
}
}
public void OnColorPicked(Color c){
m_onColorPickedEvent(c);
}
bool m_pickColor;
public static bool PickColor {
get {
return Instance.m_pickColor;
}
set {
Instance.m_pickColor = value;
}
}
#region Monobehaviours
public void Start(){
instance = this;
}
public void OnApplicationQuit (){
instance = null;
}
void OnGUI ()
{
if (m_pickColor && GUI.RepeatButton (new Rect (10, 10, ImageWidth, ImageHeight), colorPicker)) {
Vector2 pickpos = Event.current.mousePosition;
int aaa = Convert.ToInt32 (pickpos.x);
int bbb = Convert.ToInt32 (pickpos.y);
//Debug.Log (aaa + "," + bbb);
Color col = colorPickerFlipped.GetPixel (aaa, bbb);
// "col" is the color value that Unity is returning.
// Here you would do something with this color value, like
// set a model's material tint value to this color to have it change
// colors, etc, etc.
OnColorPicked (col);
if (Input.GetMouseButtonUp (0)) {
m_pickColor = false;
}
}
}
#endregion
}
Meanwhile, in another code file (like where your GUI is), you can subscribe to the ColorPicker
's delegate and event system by doing the following:
void OnGUI(){
if(GUI.Button(new Rect(5,55, 200, 20),"Change Color!")){
ColorPicker.PickColor = true;
ColorPicker.OnColorPickedEvent += new ColorPicker.OnColorPickedHandler( OnPickColor );
}
}
public void OnPickColor (Color c)
{
Debug.Log(c);
}
I was reading this much interesting thread about color picking, so first of all thanks for this, it saved me some searching.
Reading the following, I thought I might add my contribution :
Now, for some reason the closer I would get to "Black" the brighter the color would get. So my solution was to display one texture and read a color from another that was flipped.
That's because textures are stored and read "flipped" on the Y axis. You can change your code with something like :
int bbb = ImageHeight - Convert.ToInt32 (pickpos.y);
This will read the texture in the proper direction. Hope it helps..
Answer by frogsbo · Jun 07, 2014 at 12:34 PM
ar i dunno:
if (GUI.Button(Rect(160,120,150,20),"screentest"))
{
// Make a new texture of the right size and
// read the camera image into it.
var tex = new Texture2D(Screen.width, Screen.height);
tex.ReadPixels(new Rect(0, 0, 128, 128), 0, 0);
tex.Apply();
// Set the display texture to the newly captured image.
//display.material.mainTexture = tex;
// Reset the grab variable to avoid making multiple
// captures.
}