Tasharen Entertainment Forum

Support => NGUI 3 Support => Topic started by: Roots on April 18, 2012, 11:29:25 PM

Title: Color Picker
Post by: Roots on April 18, 2012, 11:29:25 PM
Any suggestion on how to go about a simple color picker inside NGUI? Just some tips or suggestions? Ideally more than 16 colors e.g. 256

thanks
Title: Re: Color Picker
Post by: ArenMook on April 18, 2012, 11:35:33 PM
Coder's solution:

Create a function that takes an XY position from 0 to 1. Inside that function, use some formula to return a color at those positions. This function should be able to generate a color gradient when used over a large area. You then use this function to both generate the texture as well as sample the color when the OnPress or OnDrag is received.

Tweaker's solution:

Create a gradient texture in Photoshop, or just take a picture of one. Make sure to set "readable" on the texture import properties. Use UITexture to draw it. Set it to use top-left pivot. In OnPress & OnDrag, calculate the position of the UICamera.lastTouchPosition relative to the widget's origin (the top-left corner). Texture2D.ReadPixels the color at that coordinate.
Title: Re: Color Picker
Post by: Roots on April 18, 2012, 11:59:24 PM
Thanks, think that the importing a texture and just doing a read pixel is likely the cleanest. Feel a little bad because i could have come up with that myself.

Do you ever sleep?
Title: Re: Color Picker
Post by: ArenMook on April 19, 2012, 12:05:14 AM
Sure I do... every so often!  8)
Title: Re: Color Picker
Post by: Fbary on June 04, 2012, 11:16:35 AM
Sorry if I re-open this thread, but I need a little help with this kind of stuff =P

I've fully created a color picker working with OnGui. Now, to avoid all the problems linked with this structure, i started working with Ngui. Here i've found some problems..

I created an UITexture in the scene, and with the OnPress/OnDrag functions i worked as you said..but it doesn't want to work =P

I used Texture2D.getpixel instead ReadPixel, as I did in my original script. I save my position during the OnPress with UICamera.lastTouchPosition, then I convert the x and y coord from float to int. At last I use getpixel. All this lines worked perfectly with my OnGui script, what I need to change to make it works?

The mainTexture in UITexture is a "Texture" type, not "Texture2D". Can be possible to use that texture for my Picker, without an extra cast..?

If i can't solve these problems, i'll work without OnPress function, but just with a normal raycast structure..

I'll wait for answers, thank you for your patience =P


Title: Re: Color Picker
Post by: ArenMook on June 04, 2012, 02:56:44 PM
You need to be more clear... which part is not working?
Title: Re: Color Picker
Post by: Fbary on June 04, 2012, 06:44:06 PM
I think my problem is in the getPixel or in the UICamera.lastTouchPosition.

Have you ever tried to build a color picker using Ngui? Just to know if you have a working example, or something else..
Title: Re: Color Picker
Post by: ArenMook on June 04, 2012, 08:14:36 PM
I haven't but others have.
Title: Re: Color Picker
Post by: Skared Creations on July 12, 2012, 12:03:38 PM
In OnPress & OnDrag, calculate the position of the UICamera.lastTouchPosition relative to the widget's origin (the top-left corner). Texture2D.ReadPixels the color at that coordinate.

I'm having some problems to achieve this, probably I'm doing something wrong. To calculate the lastTouchPosition relative to the UITexture I'm subtracting from it the screen point of the widget's transform:

  1. // This code is executed in a script attached to the UITexture which contains the wheel texture
  2. Vector3 textureWheelPos = UICamera.currentCamera.WorldToScreenPoint(transform.position);
  3. Vector2 pos = UICamera.lastTouchPosition - textureWheelPos;
  4.  

I'm almost sure that I'm doing it wrong, can you please help?
Title: Re: Color Picker
Post by: ArenMook on July 12, 2012, 04:38:31 PM
When are you doing that? UICamera.currentCamera is only valid during event callbacks such as OnPress and OnDrag. Other than that it seems fine. Just keep in mind that the 'transform.position' will be your widget's pivot point... which by default is center, not top-left.
Title: Re: Color Picker
Post by: Skared Creations on July 12, 2012, 04:53:40 PM
Yep I fixed everything, I was getting the transform position on Start but the widget is on an animated panel so it got the position when the panel was out of the screen, now it works :)
Title: Re: Color Picker
Post by: Disastercake on February 12, 2013, 02:17:37 AM
I'm trying to adjust the above code to my own using the following:
  1. public Texture2D texture2D = null;
  2.        
  3.        
  4.         void Awake()
  5.         {
  6.                 texture2D = GetComponent<UITexture>().mainTexture as Texture2D;
  7.         }
  8.  
  9. void OnClick()
  10.         {
  11.                 Vector3 textureWheelPos = UICamera.currentCamera.WorldToScreenPoint(transform.position);
  12.                
  13.                 Vector2 pos = new Vector2(textureWheelPos.x, textureWheelPos.y);
  14.                
  15.                 pos = UICamera.lastTouchPosition - pos;
  16.                
  17.                 int x = (int)pos.x;
  18.                
  19.                 int y = (int)pos.y;
  20.                
  21.                 Color color = texture2D.GetPixel(x, y);
  22.                
  23.                 Debug.Log("X: " + x + "; Y: " + y + "; Red: " + color.r + "Green: " + color.g + "Blue: " + color.b + "Alpha: " + color.a);
  24.         }
  25.  

However, no matter where I click, I get a (0, 0, 0, 1) color returned to me.

What am I doing wrong?


Edit:
I've changed the pivot point to bottom left, and it's giving me much closer colors, however it's still not perfect.  It appears to be giving me colors near the target area, not directly on it.  How do I make it so it knows exactly where I'm clicking?
Title: Re: Color Picker
Post by: ArenMook on February 12, 2013, 10:44:29 AM
Flip the Y value instead. It's negative -- so add it to +1. I am guessing the pivot point of the UITexture doesn't match the origin of the texture itself.
Title: Re: Color Picker
Post by: Disastercake on February 12, 2013, 10:47:14 AM
Hey Aren,

I just edited my "edited" section above.  What do you take of this new information?

My guess is it has something to do with me having to type cast to int and not getting perfect results.

I seem to always get an X value with a decimal ALWAYS at .9, and a Y with a decimal ALWAYS at .8 (example: (186.9, 114.8 ) and (1.9, 1.8 )).

I've attached the image I've been using to test, and have made 2 black dots at the top of the color wheel.  The one in the yellow right underneath "1" shows the spot I clicked in Unity,  And the other black dot (a few sections down in 36) shows a number Unity is giving me.
Title: Re: Color Picker
Post by: ArenMook on February 12, 2013, 10:58:29 AM
I see you transforming from world to screen point... but you don't take the UITexture's origin point into account at all.
Title: Re: Color Picker
Post by: Disastercake on February 12, 2013, 11:03:23 AM
Where would you take that part into account?  I'm not sure what you mean by this, because I thought that WAS the origin point.

I've updated my previous post with an example image to help grasp the problem better.


To clarify further, it appears to be giving me correct coordinates in the debug, since clicking in the bottom left hand corner of the image gives back 1,1.

Also, changing my screen size seems to throw off how wrong the point click is even more.  Using a small screen gives me a blue color when clicking near the "1".
Title: Re: Color Picker
Post by: ArenMook on February 13, 2013, 02:11:17 PM
Ok let's start from the beginning.

transform.position is world space, which you shouldn't be using it at all. Touch position is in screen space: UICamera.lastTouchPosition (http://www.tasharen.com/ngui/docs/class_u_i_camera.html#a671393febe2d9a4e0b4eb392154144c3).

Take your widget's cachedTransform.localPosition and apply the UIWidget's pivotOffset, scaled by the transform's scale:
  1. cachedTransform.localScale.Scale((Vector3)widget.pivotOffset);
...this gives you the pixel-size pivot offset that you then add to your UIWidget's cachedTransform.localPosition to figure out the actual origin point (top left corner).

You may then need to add parent transform offsets leading up to this widgets if you've moved one of the parents. Make sure to add up localPosition, never transform.position.

Now that you have true screen-coordinate full top-left corner, the rest should be easy.