Making a color wheel / color picker?

Hello, I was wondering how I can convert the mouse position to a point on a texture? If I can figure out how to do that then I am assuming I could use “Texture2D.ReadPixels” to get the color under the mouse position, am I correct?

I am having trouble trying to figure this one out. Any help would be appreciated. Thank you.

Anybody?

One way to go would be to use a raycast to detect the point on the object under the mouse (see this example script). The RaycastHit object returned by the raycast contains the texture coordinate of the target point. Rather than use Texture2D.GetPixels (ReadPixels actually does something slightly different), you could pass the texture coordinate directly to Texture2D.GetPixelBilinear and avoid calculating the pixel position of the coordinate.

yay! :smile: Thanks very much andeeee. I will try that out and post my results.

Check out UnityPaint, it has an excellent example of this:
http://forum.unity3d.com/viewtopic.php?t=24167&highlight=unitypaint

@ andeeee-
Hey, I am trying to piece this together, and am a little unclear. Does the physics.raycast work for GUI elements?

@ bigkahuna-
I am looking at the code for UnityPaint right now . . . although I am a bit lost. I am assuming the function that handles the RGB picking is the RGBCircle function . . right? Im not seeing anywhere where the guy uses raycasting, but a lot of:

pos = (Vector2 (Mathf.Cos ( hsb.h*360*Mathf.Deg2Rad), -Mathf.Deg2Rad))*r.width*hsb.s/2);

I see the if(Input.GetMouseButton(0)) section, so I am pretty sure the code to get the clicked on color is there, but im not quite making sense of it. :frowning:

You can make a color picker hassle-free right in the UI.

This is what I use to tint parts of the character in my character editor.

You can even hold the mouse button down and move the cursor around on the picker and it updates realtime on the model, smoothly changing the colors if your texture has smooth color-gradients.

colorPicker is a Texture2D, col is obviously a Color.
xxx and yyy are just the position of the button on the screen. Makes it easy to duplicate and set up if you need several colorpickers.
You will have to adjust the numbers for offset and textureheight depending on the texture you use (the 9, 5 and 41). Also make sure the button is a bit bigger than the texture, or it will get squashed and it stops working pixelperfectly. (I needed a buttonheight of 55 for my texheight of 41 for instance. I am sure there are ways to make the button fit better if you play with the button styles, but I liked how it looked out of the box, so I chose the easy road)

if (GUI.RepeatButton (Rect (xxx,yyy,215,55), colorPicker)) {
				pickpos = Event.current.mousePosition;
				aaa = pickpos.x-xxx-9;
				bbb = pickpos.y-yyy-5;
				col = colorPicker.GetPixel(aaa,41-bbb);

				model.materials[matnum].SetColor("_Color",col);
			}

Very nice solution GaborD, I’ll have to remember this one!

:lol: Awesome GaborD. I will try your solution as well. Seems pretty straight forward.

So far I have a function that uses a black and white image, and tints it with a predetermined color. The last part I am missing is to be able to pick the color, so I am hoping to get this part done soon. As soon as I figure it out I will post my result so as to help other n00bs out. Thanks again for the replies everyone.

Hey GaborD, it took me a bit to get the hang of it, but I got it to work! :smile: Thank you so much for sharing this.

It took a bit of messing with the offsets and image sizes to get the right combination, but I think I found one that works well.

As a side note, where are you getting the 9 and 5 from in your code? Are those just random numbers that seemed to work well, or is there a basis for arriving at those? Just curious, because I would like to fully understand whats going on as I am trying to learn Unity. Thanks again.

There is some space between the button edge and the texture edge plus my texture had a thin border too, so those added up to the values that worked.
I just tried around until it was pixelperfect. :slight_smile:

awesome, thanks again! :smile:

@Fishypants - I’m really interested in getting this to work for an Avatar creator, using the color selected as the base for a character mesh. Would you be able to share your code in getting this to work, I know that you said GaborD gave you a hand? I’m really new to codding so I don’t know how to use GaborD’s script…

Thanks!

Thanks GaborD for sharing seems to works fine !!

Adam -

I modified GaborD’s original code, and converted it to C# (since thats what I am using now). Hopefully you find it useful:

Drag this onto a game object. In the inspector, drag an image into the “Color Picker” slot that you want to use as a color picker. Set the “Image Width” and “Image Height” attributes to be the size of the image. When you click and drag inside the image, color information should show up in the Console.

using UnityEngine;
using System;
using System.Collections;

public class ColorPicker : MonoBehaviour {
	public Texture2D colorPicker;
	public int ImageWidth = 100;
	public int ImageHeight = 100;

	void OnGUI(){
		if (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);
				Color col = colorPicker.GetPixel(aaa,41-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.
				//
				// Right now we are just printing the RGBA color values to the Console
				Debug.Log(col);
		}
	}
}

You’ll have to find out how to change a models color value somewhere in the forum, as I don’t remember how to do it offhand and I don’t have my old example on me (computer died) (>.<)

I’d like to share what I did, in UnityScript not C#.

Have a look :

var target : Transform;  // change color of :

// var background : Texture2D;  // add a background (see line 34)

var colorPicker : Texture2D;  // next settings for texture 256x256   /!\ Don't forget to make the texture readable (Select your texture : in Inspector [Texture Import Setting] > Texture Type > Advanced > Read/Write enabled > True  then Apply). 

var imageX : int = 0;
var imageY : int = 0;
var imageWidth : int = 260;
var imageHeight : int = 260;
var buttonBorderH : float = 4.0;
var buttonBorderV : float = 0.0;

 
function OnGUI() {
		
    if (GUI.RepeatButton(Rect(imageX, imageY, imageWidth, imageHeight), colorPicker)) { 

        var pickpos : Vector2 = Event.current.mousePosition; // give mouse position Vector2(x,y)

        var aaa : int = pickpos.x - imageX - buttonBorderH;

        var bbb : int =  pickpos.y - imageY - buttonBorderV;

        var col : Color = colorPicker.GetPixel(aaa,colorPicker.height-bbb); // return pixel color at coordinates(x,y) ! of texture2D !


            // Debug.Log(pickpos);
            
            target.renderer.material.color = col;

    }
	
	// GUI.Label(Rect(imageX + 5.5, imageY + 2.5, 254, 254), background);        // background Label
}


@script ExecuteInEditMode  // make it visible in Game window without pressing Play

Works fine. Up for more advices - still beginner myself.

Wow, interesting solutions. Can someone upload the particular color picker texture that worked perfectly

Thanks in advance

Here is a good color picker for those who need it…

1176211--45157--$colorpicker_texture.png

What are the offsets you used for this one?

Dimensions for the posted image are 400 x 400. If you use a different image, set ImageWidth and ImageHeight to the dimensions of the image.

Many thanks to the original coders; I found this to be very useful.