栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 游戏开发 > 其他

【Unity3D实现自定义调色板】

其他 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【Unity3D实现自定义调色板】

Unity3D实现自定义调色板

由于需要制作一个调色板,也找了一些参考例子,但都是通过RGB来实现的,看上去不符合我的预期。
在看了Color相关属性方法,发现HSV的相关值坐标轴与颜色有对应关系。
然后我根据该对应关系制作了一个调色板,记录并分享一下。

话不多说先看效果图


源码如下

调色板

using UnityEngine;
using UnityEngine.UI;


public class ColorPick : MonoBehaviour
{
    public RawImage paint;
    public RawImage saturation;
    public RawImage hue;
    public RawImage alpha;

    public Button paintBtn;
    public ScrollRectClick scrollRectSaturation;
    public Scrollbar scrollbarHue;
    public Scrollbar scrollbarAlpha;
    private Vector4 currentColorHSV = new Vector4(0, 1, 1, 1);

    private readonly float piexlWidth = 256.0f;
    private readonly float piexlHeight = 256.0f;
    private readonly float huePiexWidth = 50.0f;
    private Texture2D saturationTexture2D;
    private Texture2D hueTexture2D;
    private Texture2D alphaTexture2D;

    [SerializeField]
    private bool isShowPanel = true;

    public Color PaintColor
    {
        get { return HSVToRGB(currentColorHSV); }
    }
    private void Awake()
    {
        InitPaintPick();
    }

    private void InitPaintPick()
    {
        paintBtn.onClick.AddListener(OnPaintClick);
        scrollRectSaturation.onValueChanged.AddListener(OnSaturationClick);
        scrollbarHue.onValueChanged.AddListener(OnHueClick);
        scrollbarAlpha.onValueChanged.AddListener(OnAlphaClick);

        saturationTexture2D = new Texture2D((int)piexlWidth, (int)piexlHeight);
        saturation.texture = saturationTexture2D;

        hueTexture2D = new Texture2D((int)huePiexWidth, (int)piexlHeight);
        hue.texture = hueTexture2D;

        alphaTexture2D = new Texture2D((int)huePiexWidth, (int)piexlHeight);
        alpha.texture = alphaTexture2D;

        scrollbarHue.value = 1 - currentColorHSV.x;
        scrollbarAlpha.value = currentColorHSV.w;

        OnPaintClick();
        UpdateSaturation(currentColorHSV);
        UpdateHue();
        UpdateAlpha();
        UpdateSaturationPoint(currentColorHSV);
        PaintChange();
    }

    private void PaintChange()
    {
        paint.color = PaintColor;
    }

    void OnPaintClick()
    {
        saturation.gameObject.SetActive(isShowPanel);
        hue.gameObject.SetActive(isShowPanel);
        alpha.gameObject.SetActive(isShowPanel);
        isShowPanel = !isShowPanel;
    }

    public void OnSaturationClick(Vector2 point)
    {
        Vector2 hsv = GetSaturationHSV(point);
        currentColorHSV.y = hsv.x;
        currentColorHSV.z = hsv.y;
        UpdateSaturationPoint(currentColorHSV);
        PaintChange();
        UpdateAlpha();
    }

    public void OnHueClick(float value)
    {
        currentColorHSV.x = 1 - value;
        UpdateSaturationPoint(currentColorHSV);
        PaintChange();
        UpdateSaturation(currentColorHSV);
        UpdateAlpha();
    }

    public void OnAlphaClick(float value)
    {
        currentColorHSV.w = value;
        UpdateSaturationPoint(currentColorHSV);
        PaintChange();
    }

    public void UpdateSaturation(Vector4 hsv)
    {
        for (int y = 0; y < piexlHeight; y++)
        {
            for (int x = 0; x < piexlWidth; x++)
            {
                Color pixColor = GetSaturation(hsv, x / piexlWidth, y / piexlHeight);
                saturationTexture2D.SetPixel(x, y, pixColor);
            }
        }
        saturationTexture2D.Apply();
        saturation.texture = saturationTexture2D;
    }

    public void UpdateHue()
    {
        for (int y = 0; y < piexlHeight; y++)
        {
            for (int x = 0; x < huePiexWidth; x++)
            {
                Color pixColor = GetHue(y / piexlHeight);
                hueTexture2D.SetPixel(x, y, pixColor);
            }
        }
        hueTexture2D.Apply();
        hue.texture = hueTexture2D;
    }

    public void UpdateAlpha()
    {
        for (int y = 0; y < piexlHeight; y++)
        {
            Color pixColor = GetAlpha(y / piexlHeight);
            for (int x = 0; x < huePiexWidth; x++)
            {
                alphaTexture2D.SetPixel(x, (int)piexlHeight - y, pixColor);
            }
        }
        alphaTexture2D.Apply();
        alpha.texture = alphaTexture2D;
    }

    public void UpdateSaturationPoint(Vector4 hsv)
    {
        Vector2 saturationPoint = GetSaturationPoint(hsv);
        scrollRectSaturation.content.anchoredPosition = saturationPoint;
    }

    private Color GetSaturation(Vector4 hsv, float x, float y)
    {
        Vector4 saturationHSV = hsv;
        saturationHSV.y = x;
        saturationHSV.z = y;
        saturationHSV.w = 1;
        return HSVToRGB(saturationHSV);
    }

    private Color GetHue(float y)
    {
        Vector4 hueHSV = new Vector4(y, currentColorHSV.y, currentColorHSV.z, 1);
        return HSVToRGB(hueHSV);
    }

    private Color GetAlpha(float y)
    {
        Vector4 hueHSV = new Vector4(currentColorHSV.x, currentColorHSV.y, currentColorHSV.z, y);
        return HSVToRGB(hueHSV);
    }

    private Vector2 GetSaturationHSV(Vector2 point)
    {
        Vector2 hsv = new Vector2();
        hsv.x = point.x / saturation.rectTransform.sizeDelta.x + 0.5f;
        hsv.y = point.y / saturation.rectTransform.sizeDelta.y + 0.5f;
        return hsv;
    }

    private Vector2 GetSaturationPoint(Vector4 hsv)
    {
        Vector2 point = new Vector2();
        point.x = (hsv.y - 0.5f) * saturation.rectTransform.sizeDelta.x;
        point.y = (hsv.z - 0.5f) * saturation.rectTransform.sizeDelta.y;
        return point;
    }

    private Color HSVToRGB(Vector4 hsv)
    {
        Color color = Color.HSVToRGB(hsv.x, hsv.y, hsv.z);
        color.a = hsv.w;
        return color;
    }
}

自定义饱和度点击面板

using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class ScrollRectClick : Selectable, IPointerDownHandler, IDragHandler, IEventSystemHandler
{
    public Camera m_camera;
    public RectTransform content;
    public Vector3 contentPoint;
    public Vector4 limitBounds;
    public ScrollRect.ScrollRectEvent onValueChanged;

    [SerializeField]
    private bool isScreenSpace = true;
    private RectTransform rect;
    private Vector3 screenPoint;

    protected override void Awake()
    {
        rect = transform as RectTransform;
        limitBounds.x = -rect.sizeDelta.x / 2;
        limitBounds.y = rect.sizeDelta.x / 2;
        limitBounds.z = -rect.sizeDelta.y / 2;
        limitBounds.w = rect.sizeDelta.y / 2;
    }

    public override void OnPointerDown(PointerEventData eventData)
    {
        if (isScreenSpace)
        {
            contentPoint = rect.InverseTransformPoint(eventData.position);
        }
        else
        {
            screenPoint = m_camera.WorldToScreenPoint(transform.position);
            Vector3 world = m_camera.ScreenToWorldPoint(new Vector3(eventData.position.x, eventData.position.y, screenPoint.z));
            contentPoint = rect.InverseTransformPoint(world);
        }
        contentPoint.x = Mathf.Max(limitBounds.x, Mathf.Min(limitBounds.y, contentPoint.x));
        contentPoint.y = Mathf.Max(limitBounds.z, Mathf.Min(limitBounds.w, contentPoint.y));
        content.anchoredPosition = contentPoint;
        onValueChanged.Invoke(contentPoint);
    }

    public void OnDrag(PointerEventData eventData)
    {
         if (isScreenSpace)
        {
            contentPoint = rect.InverseTransformPoint(eventData.position);
        }
        else
        {
            screenPoint = m_camera.WorldToScreenPoint(transform.position);
            Vector3 world = m_camera.ScreenToWorldPoint(new Vector3(eventData.position.x, eventData.position.y, screenPoint.z));
            contentPoint = rect.InverseTransformPoint(world);
        }
        contentPoint.x = Mathf.Max(limitBounds.x, Mathf.Min(limitBounds.y, contentPoint.x));
        contentPoint.y = Mathf.Max(limitBounds.z, Mathf.Min(limitBounds.w, contentPoint.y));
        content.anchoredPosition = contentPoint;
        onValueChanged.Invoke(contentPoint);
    }
}

最后附赠案例地址

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/901311.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号