当前位置:网站首页>Unity 颜色板|调色板|无级变色功能
Unity 颜色板|调色板|无级变色功能
2022-07-06 16:05:00 【Fuuyg】
效果
Unity 通过UGUI实现无级变色的调色板功能,非常的简单好用。
项目git地址
https://github.com/zrzhang76/UnityColorBoard
代码(写这个完全是因为CSDN嫌我字数少,建议直接看项目)
颜色板部分
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
namespace CSharp.UI.ColorBoard
{
public class ColorBoard : MonoBehaviour, IPointerClickHandler, IDragHandler
{
//显示颜色的Texture
Texture2D tex2d;
//RawImage组件
RawImage ri;
//像素宽度高度256(默认值)
int TexPixelLength = 256;
int TexPixelHeight = 256;
//公共组件
public Slider sliderCRGB;
public ColorHue colorHue;
//颜色数组
UnityEngine.Color[,] arrayColor;
//自身的Transform
RectTransform rt;
//颜色聚焦点的圆圈
public RectTransform circleRect;
public delegate void ColorChangeDelegate(Color color);
public event ColorChangeDelegate OnColorChanged;
private void Awake()
{
ri = GetComponent<RawImage>();
rt = GetComponent<RectTransform>();
circleRect = transform.Find("img_cursor").GetComponent<RectTransform>();
TexPixelLength = (int)rt.sizeDelta.x;
TexPixelHeight = (int)rt.sizeDelta.y;
//初始化颜色数组
arrayColor = new UnityEngine.Color[TexPixelLength, TexPixelHeight];
//创建一个固定长宽的Texture
tex2d = new Texture2D(TexPixelLength, TexPixelHeight, TextureFormat.RGB24, true);
//组件赋值图片
ri.texture = tex2d;
ri.texture.wrapMode = TextureWrapMode.Clamp;
//初始化设置板子的颜色为红色
SetColorPanel(UnityEngine.Color.red);
sliderCRGB.onValueChanged.AddListener(OnCRGBValueChanged);
}
//颜色放生变化的监听
void OnCRGBValueChanged(float value)
{
UnityEngine.Color endColor=colorHue.GetColorBySliderValue(value);
SetColorPanel(endColor);
var color = GetColorByPosition(circleRect.anchoredPosition);
OnColorChanged?.Invoke(color);
}
//设置板子的颜色
public void SetColorPanel(UnityEngine.Color endColor)
{
UnityEngine.Color[] CalcArray = CalcArrayColor(endColor);
//给颜色板子填入颜色,并且应用
tex2d.SetPixels(CalcArray);
tex2d.Apply();
}
//通过一个最终颜色值,计算板子上所有像素点应该的颜色,并返回一个数组
UnityEngine.Color[] CalcArrayColor(UnityEngine.Color endColor)
{
//计算最终值和白色的差值在水平方向的平均值,用于计算水平每个像素点的色值
UnityEngine.Color value = (endColor - UnityEngine.Color.white) / (TexPixelLength - 1);
for (int i = 0; i < TexPixelLength; i++)
{
arrayColor[i, TexPixelHeight - 1] = UnityEngine.Color.white + value * i;
}
// 同理,垂直方向
for (int i = 0; i < TexPixelLength; i++)
{
value = (arrayColor[i, TexPixelHeight - 1] - UnityEngine.Color.black) / (TexPixelHeight - 1);
for (int j = 0; j < TexPixelHeight; j++)
{
arrayColor[i, j] = UnityEngine.Color.black + value * j;
}
}
//返回一个数组,保存了所有颜色色值
List<UnityEngine.Color> listColor = new List<UnityEngine.Color>();
for (int i = 0; i < TexPixelHeight; i++)
{
for (int j = 0; j < TexPixelLength; j++)
{
listColor.Add(arrayColor[j, i]);
}
}
return listColor.ToArray();
}
/// <summary>
/// 获取颜色by坐标,坐标是Texture上面的二维坐标
/// </summary>
/// <param name="pos"></param>
/// <returns></returns>
public UnityEngine.Color GetColorByPosition(Vector2 pos)
{
Texture2D tempTex2d = (Texture2D)ri.texture;
UnityEngine.Color getColor = tempTex2d.GetPixel((int)pos.x, (int)pos.y);
return getColor;
}
public Vector2 GetClampPosition(Vector2 touchPos)
{
Vector2 vector2 = new Vector2(touchPos.x, touchPos.y);
vector2.x = Mathf.Clamp(vector2.x, 0.001f, rt.sizeDelta.x);
vector2.y = Mathf.Clamp(vector2.y, 0.001f, rt.sizeDelta.y);
return vector2;
}
//点击事件
public void OnPointerClick(PointerEventData eventData)
{
Vector3 wordPos;
//将UGUI的坐标转为世界坐标
if (RectTransformUtility.ScreenPointToWorldPointInRectangle(rt, eventData.position, eventData.pressEventCamera, out wordPos))
circleRect.position = wordPos;
circleRect.anchoredPosition = GetClampPosition(circleRect.anchoredPosition);
var color = GetColorByPosition(circleRect.anchoredPosition);
OnColorChanged?.Invoke(color);
}
//拖拽事件
public void OnDrag(PointerEventData eventData)
{
Vector3 wordPos;
//将UGUI的坐标转为世界坐标
if (RectTransformUtility.ScreenPointToWorldPointInRectangle(rt, eventData.position, eventData.pressEventCamera, out wordPos))
circleRect.position = wordPos;
circleRect.anchoredPosition = GetClampPosition(circleRect.anchoredPosition);
var color = GetColorByPosition(circleRect.anchoredPosition);
OnColorChanged?.Invoke(color);
}
}
}
色相条部分
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ColorHue : MonoBehaviour
{
//绘制颜色的Texture
Texture2D tex2d;
//图片展示组件
RawImage ri;
//长宽
int TexPixelWdith = 952;
int TexPixelHeight = 16;
//颜色的数组
UnityEngine.Color[,] arrayColor;
private void Awake()
{
ri = gameObject.GetComponent<RawImage>();
//初始化颜色和Texture
arrayColor = new UnityEngine.Color[TexPixelWdith, TexPixelHeight];
tex2d = new Texture2D(TexPixelWdith, TexPixelHeight, TextureFormat.RGB24,true);
//计算颜色
UnityEngine.Color[] calcArray = CalcArrayColor();
//展示出来
tex2d.SetPixels(calcArray);
tex2d.Apply();
ri.texture = tex2d;
ri.texture.wrapMode = TextureWrapMode.Clamp;
}
//计算色相条上面需要展示的颜色数组
UnityEngine.Color[] CalcArrayColor()
{
//计算水平像素的等分增量
int addValue = (TexPixelWdith - 1) / 3;
//
for (int i = 0; i < TexPixelHeight; i++)
{
arrayColor[0, i] = UnityEngine.Color.red;
arrayColor[addValue, i] = UnityEngine.Color.green;
arrayColor[addValue+addValue, i] = UnityEngine.Color.blue;
arrayColor[TexPixelHeight - 1, i] = UnityEngine.Color.red;
}
UnityEngine.Color value = (UnityEngine.Color.green - UnityEngine.Color.red)/addValue;
for (int i = 0; i < TexPixelHeight; i++)
{
for (int j = 0; j < addValue; j++)
{
arrayColor[j, i] = UnityEngine.Color.red + value * j;
}
}
value = (UnityEngine.Color.blue - UnityEngine.Color.green)/ addValue;
for (int i = 0; i < TexPixelHeight; i++)
{
for (int j = addValue; j < addValue*2; j++)
{
arrayColor[j, i] = UnityEngine.Color.green + value * (j-addValue);
}
}
value = (UnityEngine.Color.red - UnityEngine.Color.blue) / ((TexPixelWdith - 1)-addValue-addValue);
for (int i = 0; i < TexPixelHeight; i++)
{
for (int j = addValue*2; j < TexPixelWdith - 1; j++)
{
arrayColor[j, i] = UnityEngine.Color.blue + value * (j- addValue * 2);
}
}
List<UnityEngine.Color> listColor = new List<UnityEngine.Color>();
for (int i = 0; i < TexPixelHeight; i++)
{
for (int j = 0; j < TexPixelWdith; j++)
{
listColor.Add(arrayColor[j, i]);
}
}
return listColor.ToArray();
}
/// <summary>
/// 获取颜色 根据高度
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public Color GetColorBySliderValue(float value)
{
float clampValue = Mathf.Clamp(value, 0.001f, 0.999f);
Color getColor=tex2d.GetPixel((int)((TexPixelWdith-1)*clampValue),0);
return getColor;
}
}
制作不易,给个赞呗~~
边栏推荐
- (1)长安链学习笔记-启动长安链
- If the request URL contains jsessionid, the solution
- Example code of MySQL split string as query condition
- Knowledge * review
- Cloud native (32) | kubernetes introduction to platform storage system
- 【通信】两层无线 Femtocell 网络上行链路中的最优功率分配附matlab代码
- AI金榜题名时,MLPerf榜单的份量究竟有多重?
- Nftscan Developer Platform launches Pro API commercial services
- Why are some people still poor and living at the bottom of society even though they have been working hard?
- A few suggestions for making rust library more beautiful! Have you learned?
猜你喜欢
What can be done for traffic safety?
Why are some people still poor and living at the bottom of society even though they have been working hard?
JDBC programming of MySQL database
谁说新消费品牌大溃败?背后有人赢麻了
Gpt-3 is a peer review online when it has been submitted for its own research
I've been laid off, and I'll lose money for everything. The days when I once made a monthly salary of 20000 are not coming back
GPT-3当一作自己研究自己,已投稿,在线蹲一个同行评议
11 preparations for Web3 and Decentralization for traditional enterprises
Gradle知识概括
Restoration analysis of protobuf protocol of bullet screen in station B
随机推荐
【系统分析师之路】第七章 复盘系统设计(面向服务开发方法)
同构+跨端,懂得小程序+kbone+finclip就够了!
(1) Chang'an chain learning notes - start Chang'an chain
Modules that can be used by both the electron main process and the rendering process
A few suggestions for making rust library more beautiful! Have you learned?
Station B boss used my world to create convolutional neural network, Lecun forwarding! Burst the liver for 6 months, playing more than one million
js对JSON数组的增删改查
(LeetCode)两数之和
Let me ask you if there are any documents or cases of flynk SQL generation jobs. I know that flynk cli can create tables and specify items
leetcode:236. 二叉树的最近公共祖先
11 preparations for Web3 and Decentralization for traditional enterprises
今日睡眠质量记录78分
Stop saying that microservices can solve all problems
The intranet penetrates the zerotier extranet (mobile phone, computer, etc.) to access intranet devices (raspberry pie, NAS, computer, etc.)
The programmer refused the offer because of low salary, HR became angry and netizens exploded
谁说新消费品牌大溃败?背后有人赢麻了
Isomorphism + cross end, knowing applet +kbone+finclip is enough!
基础图表解读“东方甄选”爆火出圈数据
If the request URL contains jsessionid, the solution
NFTScan 开发者平台推出 Pro API 商业化服务