Unity实现颜色色盘功能

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一条闲の鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值