Unity实现颜色色盘功能
功能描述
在Unity中实现一个拾取颜色的色盘功能。通过控制色盘中的控制器,选择对应色盘的颜色显示在UI上。
项目结构
UI组件
- ColorRingPanel: 用与挂载ColorManager脚本入口,获取右侧色条滑动组件和,当前选中颜色色块UI;
- ColorPanel: 挂载ColorPanel脚本,获取并显示选择色域的所有颜色,通过其上corcle(挂载ColorCircle脚本)UI控制选中的颜色;
- ColorRGB:右侧色条显示区域,挂载ColorRGB脚本通过滑动条控制选中的颜色色域
脚本文件和对应代码
- ColorManager:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
/**********************************
*作者:一条闲の鱼
*时间:2021-12-31
*版本:1.0
*Unity版本:2019.3.14f1
**********************************/
/// <summary>
/// 描述:赋值管理
/// </summary>
public class ColorManager : MonoBehaviour
{
RectTransform rt;
private ColorRGB CRGB;
private ColorPanel CP;
private ColorCircle CC;
public Slider sliderCRGB;
public Image colorShow;
void OnDisable()
{
CC.getPos -= CC_getPos;
}
private void CC_getPos(Vector2 pos)
{
Color getColor = CP.GetColorByPosition(pos);
colorShow.color = getColor;
}
// Use this for initialization
void Start()
{
rt = GetComponent<RectTransform>();
CRGB = GetComponentInChildren<ColorRGB>();
CP = GetComponentInChildren<ColorPanel>();
CC = GetComponentInChildren<ColorCircle>();
sliderCRGB.onValueChanged.AddListener(OnCRGBValueChanged);
CC.getPos += CC_getPos;
}
void OnCRGBValueChanged(float value)
{
Color endColor = CRGB.GetColorBySliderValue(value);
CP.SetColorPanel(endColor);
CC.setShowColor();
}
}
- ColorPanel:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
/**********************************
*作者:一条闲の鱼
*时间:2021-12-31
*版本:1.0
*Unity版本:2019.3.14f1
**********************************/
/// <summary>
/// 描述:显示左侧色块,拖动拾色环拾取当前颜色 实现色板
/// </summary>
public class ColorPanel : MonoBehaviour, IPointerClickHandler, IDragHandler
{
Texture2D tex2d;
public RawImage ri;//显示的rawimage
int TexPixelLength = 256;
Color[,] arrayColor;
RectTransform rt;
public RectTransform circleRect;
private void Start()
{
arrayColor = new Color[TexPixelLength, TexPixelLength];
tex2d = new Texture2D(TexPixelLength, TexPixelLength, TextureFormat.RGB24,
true);
ri.texture = tex2d;
rt = GetComponent<RectTransform>();
SetColorPanel(Color.red);
}
public void SetColorPanel(Color endColor)
{
Color[] CalcArray = CalcArrayColor(endColor);
tex2d.SetPixels(CalcArray);
tex2d.Apply();
}
//设置色块颜色 参数是右上角颜色
Color[] CalcArrayColor(Color endColor)
{
Color value = (endColor - Color.white) / (TexPixelLength - 1);
for (int i = 0; i < TexPixelLength; i++)
{
arrayColor[i, TexPixelLength - 1] = Color.white + value * i;
}
for (int i = 0; i < TexPixelLength; i++)
{
value = (arrayColor[i, TexPixelLength - 1] - Color.black) /
(TexPixelLength - 1);
for (int j = 0; j < TexPixelLength; j++)
{
arrayColor[i, j] = Color.black + value * j;
}
}
List<Color> listColor = new List<Color>();
for (int i = 0; i < TexPixelLength; i++)
{
for (int j = 0; j < TexPixelLength; j++)
{
listColor.Add(arrayColor[j, i]);
}
}
return listColor.ToArray();
}
/// <summary>
/// 获取颜色by坐标
/// </summary>
/// <param name="pos"></param>
/// <returns></returns>
public Color GetColorByPosition(Vector2 pos)
{
Texture2D tempTex2d = (Texture2D)ri.texture;
Color getColor = tempTex2d.GetPixel((int)pos.x, (int)pos.y);
return getColor;
}
public void OnPointerClick(PointerEventData eventData)
{
Vector3 wordPos;
//将UGUI的坐标转为世界坐标
if (RectTransformUtility.ScreenPointToWorldPointInRectangle(rt,
eventData.position, eventData.pressEventCamera, out wordPos))
circleRect.position = wordPos;
//Debug.Log(wordPos);
circleRect.GetComponent<ColorCircle>().setShowColor();
}
public void OnDrag(PointerEventData eventData)
{
Vector3 wordPos;
//将UGUI的坐标转为世界坐标
if (RectTransformUtility.ScreenPointToWorldPointInRectangle(rt,
eventData.position, eventData.pressEventCamera, out wordPos))
circleRect.position = wordPos;
if (circleRect.anchoredPosition.x <= 0)
circleRect.anchoredPosition = new Vector2(0,
circleRect.anchoredPosition.y);
if (circleRect.anchoredPosition.y <= 0)
circleRect.anchoredPosition = new Vector2(circleRect.anchoredPosition.x,
0);
if (circleRect.anchoredPosition.x >= TexPixelLength - 1)
circleRect.anchoredPosition = new Vector2(TexPixelLength - 1,
circleRect.anchoredPosition.y);
if (circleRect.anchoredPosition.y >= TexPixelLength - 1)
circleRect.anchoredPosition = new Vector2(circleRect.anchoredPosition.x,
TexPixelLength - 1);
circleRect.GetComponent<ColorCircle>().setShowColor();
}
}
-ColorCircle:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
/**********************************
*作者:一条闲の鱼
*时间:2021-12-31
*版本:1.0
*Unity版本:2019.3.14f1
**********************************/
/// <summary>
/// 描述:
/// </summary>
public class ColorCircle : MonoBehaviour, IDragHandler
{
public delegate void RetureTextuePosition(Vector2 pos);
public event RetureTextuePosition getPos;
RectTransform rt;
public int width = 256;
public int height = 256;
// Use this for initialization
void Start()
{
rt = GetComponent<RectTransform>();
}
public void OnDrag(PointerEventData eventData)
{
Vector3 wordPos;
//将UGUI的坐标转为世界坐标
if (RectTransformUtility.ScreenPointToWorldPointInRectangle(rt,
eventData.position, eventData.pressEventCamera, out wordPos))
rt.position = wordPos;
if (rt.anchoredPosition.x <= 0)
rt.anchoredPosition = new Vector2(0, rt.anchoredPosition.y);
if (rt.anchoredPosition.y <= 0)
rt.anchoredPosition = new Vector2(rt.anchoredPosition.x, 0);
if (rt.anchoredPosition.x >= width - 1)
rt.anchoredPosition = new Vector2(width - 1, rt.anchoredPosition.y);
if (rt.anchoredPosition.y >= height - 1)
rt.anchoredPosition = new Vector2(rt.anchoredPosition.x, height - 1);
getPos(rt.anchoredPosition);
}
public void setShowColor()
{
getPos(rt.anchoredPosition);
}
}
-ColorRGB:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
/**********************************
*作者:一条闲の鱼
*时间:2021-12-31
*版本:1.0
*Unity版本:2019.3.14f1
**********************************/
/// <summary>
/// 描述:显示右侧色条
/// </summary>
public class ColorRGB : MonoBehaviour
{
Texture2D tex2d;//创建临时Texture2D
public RawImage ri;
int TexPixelWdith = 16; //ColorRGB色条的宽度,
int TexPixelHeight = 256;//ColorRGB色条的高
Color[,] arrayColor;//颜色二维数组,存储图片每一个点的颜色
private void Start()
{
arrayColor = new Color[TexPixelWdith, TexPixelHeight];
tex2d = new Texture2D(TexPixelWdith, TexPixelHeight, TextureFormat.RGBA32,
true);
Color[] color = CalcArrayColor();
tex2d.SetPixels(color);
tex2d.Apply();
ri.texture = tex2d;
}
/// <summary>
/// 返回Color数组,存储色条颜色
/// </summary>
/// <returns></returns>
Color[] CalcArrayColor()
{
#region 给每一块颜色手动赋值
//方法一赋值:将条分成三份 在0 1/3 2/3 1处分别设置为红 绿 篮 红
// 这个相对方法二颜色拾取的更准一点
int addValue = (TexPixelHeight - 1) / 3;
//设置色条为 红-绿-篮-红
for (int i = 0; i < TexPixelWdith; i++)
{
arrayColor[i, 0] = Color.red;
arrayColor[i, addValue] = Color.green;
arrayColor[i, addValue + addValue] = Color.blue;
arrayColor[i, TexPixelHeight - 1] = Color.red;
}
//分段设置颜色 红-绿
Color value = (Color.green - Color.red) / addValue;
for (int i = 0; i < TexPixelWdith; i++)
{
for (int j = 0; j < addValue; j++)
{
arrayColor[i, j] = Color.red + value * j;
}
}
//分段设置颜色 绿-篮
value = (Color.blue - Color.green) / addValue;
for (int i = 0; i < TexPixelWdith; i++)
{
for (int j = addValue; j < addValue * 2; j++)
{
arrayColor[i, j] = Color.green + value * (j - addValue);
}
}
//分段设置颜色 篮-红
value = (Color.red - Color.blue) / ((TexPixelHeight - 1) - addValue -
addValue);
for (int i = 0; i < TexPixelWdith; i++)
{
for (int j = addValue * 2; j < TexPixelHeight - 1; j++)
{
arrayColor[i, j] = Color.blue + value * (j - addValue * 2);
}
}
//把所用颜色存入数组中,从左下角开始 一行一行的存入
List<Color> listColor = new List<Color>();
for (int i = 0; i < TexPixelHeight; i++)
{
for (int j = 0; j < TexPixelWdith; j++)
{
listColor.Add(arrayColor[j, i]);
}
}
//方法二:
//通过 HSV值转换成RGB
Color[] hc = new Color[TexPixelWdith * TexPixelHeight];
for (int i = 0; i < TexPixelHeight; i++)
{
for (int j = 0; j < TexPixelWdith; j++)
{
hc[j + i * TexPixelWdith] = Color.HSVToRGB((float)i/TexPixelHeight,
1f, 1f);
}
}
return hc;//listColor.ToArray();
#endregion
}
/// <summary>
/// 获取颜色 根据高度
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public Color GetColorBySliderValue(float value)
{
Color getColor = tex2d.GetPixel(0, (int)((TexPixelHeight - 1) * (1.0f -
value)));
return getColor;
}
}
运行效果
项目package地址
https://download.csdn.net/download/qq_39435884/90768894