Unity自定义UI组件(九) 颜色拾取器(下)
前言
UnityEngine没有提供类似自带颜色拾取器的组件,但是在工业三维可视化领域可能会用到类似的组件,博主这里结合Unity UGUI源码创建一个高仿unity颜色拾取器的组件,可一键创建,监听接口使用或者直接获取组件颜色。上一篇我们已经讲了部分的难点,这篇我们将剩余的难点解决,文章末尾提供Beta版下载地址(HSV颜色模式暂未开启)。
组件特点
- 无需任何asset
- 导入代码即可生成
- 调用接口方便
实现效果
- 组件效果
- 使用方法
- 实际效果
主要内容
上一篇中我们已经讲解如何去创建颜色拾取器的主体,我们这篇简单讲解一下调色板模式的切换和创建使用
- 调色板模式切换
- 创建与使用
详细讲解
调色板模式切换
通过点击按钮切换当前的调色板模式,调色板模式一共分为六种Hue,Saturation,Brightness,Red,Green,Blue,默认情况下是Hue模式是大家最为熟悉的一种模式
切换实现
切换的实现比较简单,利用状态模式,设置六种状态,在个当前状态赋值新的状态时,更新颜色拾取器相应的其他组件即可,详细见代码。
重要将一下切换模式之后,如何让调色板上的游标跟随到对应颜色的位置
游标跟随
切换颜色模式后,根据当前颜色调整右侧垂直滑动杆的值,这样会让调色板到达一个固定状态,然后根据颜色去色板匹配,但是不能挨个像素进行匹配效率太慢,Saturation、Brightness状态下调色板由两层渐变色带组成,因此需要将颜色拆分两层考虑,Red、Green、Blue模式下只有一层渐变色带,因此需要另一种方式。
Saturation、Brightness
- 获取颜色中rgb三个中较大的两个值,组成主体颜色,定位x轴坐标
- 根据最终颜色和主体颜色计算出三个通道中另一个通道的分量,定位y轴坐标
private Vector2 getPositionByMixedCT( Color color0 )
{var result = Vector2.zero;var size = m_colorPalette.GetComponent<RectTransform>().sizeDelta;switch (PaletteMode){case E_PaletteMode.Hue:break;case E_PaletteMode.Saturation:// 在获取第一层的主题色并计算出x轴坐标var x1 = m_firstLayerCT.GetPosition(color0).x;// 获取分量var red1 = color0.r;var green1 = color0.g;var blue1 = color0.b;// 分量排序ArrayList array1 = new ArrayList() { red1 , green1 , blue1 };array1.Sort();Color mainColor1;// 根据排序前两个最大值定下主体颜色if(array1[0].Equals(red1))mainColor1 = new Color(0 , green1 , blue1 , 1);else if(array1[0].Equals(green1))mainColor1 = new Color(red1,0,blue1,1);elsemainColor1 = new Color(red1,green1,0,1);// 设置垂直色带m_verticalFirstCT.SetColors(new Color[] { mainColor1 , Color.white });// 设置调色板第二层蒙版层m_secondLayerCT.SetColors(new Color[]{new Color(0, 0, 0, 0) * (1 - (float)array1[0]) + new Color(1, 1, 1, 1) * ((float)array1[0]) ,Color.black});// 获取y轴坐标,以上算法重复了一次主题色计算在m_firstLayerCT.GetPosition(color0)中已经计算过一次,后续优化掉这部分算法float y1 = (1- (float)array1[0] ) * size.y - size.y/2.0f;result = new Vector2(x1,y1);break;case E_PaletteMode.Brightness:break;}return result;
}public virtual Vector2 GetPosition( Color color0 )
{ // .... 获取主体色// 得到主题色之后,根据色带方向在最接近的两个颜色之间再通过通道分量计算出更精确的位置switch (TapeDirection){case E_DrawDirection.Vertical:// 距离主题色相邻最近的两个基础色的色带位置var position1 = new Vector2(0 , RectSize.y / 2.0f - pos1 * RectSize.y / ( m_Colors.Count - 1 ));var position2 = new Vector2(0 , RectSize.y / 2.0f - pos2 * RectSize.y / ( m_Colors.Count - 1 ));// 判断颜色距离那个颜色通道更近int sign1 = 1;if (position1.y > position2.y)sign1 = -1;elsesign1 = 1;// 获取精确坐标位置return position1 + new Vector2(0 , ( RectSize.y / ( m_Colors.Count - 1 ) ) * offset) * sign1;case E_DrawDirection.Horizontal://..同上操作}return Vector2.zero;
}
Red、Green、Blue
- 获取三个通道的分量
- 根据分量和当前模式定位xy坐标
public Vector2 GetPosition(Color color0, ColorPicker.E_PaletteMode mode)
{// 获取分量var red = color0.r;var green = color0.g;var blue = color0.b;// 调色板左下角为原点var origin = new Vector2(-RectSize.x / 2.0f , -RectSize.y / 2.0f);// 根据不同的模式直接在色板上定位switch (mode){case ColorPicker.E_PaletteMode.Red:return origin + new Vector2(RectSize.x * blue , RectSize.y * green);case ColorPicker.E_PaletteMode.Green:return origin + new Vector2(RectSize.x * blue, RectSize.y * red);case ColorPicker.E_PaletteMode.Blue:return origin + new Vector2(RectSize.x * red , RectSize.y * green);}return Vector2.zero;
}
通过以上核心算法讲解,应该对游标定位有了一个大概了解,详细设计见源码。
创建与使用
创建
看过之前几个组件的同学应该已经很熟悉是如何在Unity引擎中插入自己的组件了,这里我们不具体讲解了,实现传送门
public class SpringGUIMenuOptions
{[MenuItem("GameObject/UI/SpringGUI/ColorPicker" , false , 2071)]public static void AddColorPicker( MenuCommand menuCommand ){GameObject colorPicker =SpringGUIDefaultControls.CreateColorPicker(GetStandardResources());PlaceUIElementRoot(colorPicker,menuCommand);colorPicker.transform.localPosition = Vector3.zero;colorPicker.AddComponent<ColorPicker>();}
}
public static class SpringGUIDefaultControls
{/// <summary>/// Create Color Picker/// </summary>/// <param name="resources"></param>/// <returns></returns>public static GameObject CreateColorPicker( Resources resources ){//... //代码量过长,具体参考源码}
}
在SpringGUI体系下加入以上代码即可在UI中创建ColorPicker组件,接下来我们看看应该如何使用监听
使用
使用原理
public class ColorPicker : UIBehaviour
{[Serializable]public class ColorPickerEvent : UnityEvent<Color> { }[SerializeField]private ColorPickerEvent m_evnet = new ColorPickerEvent();public ColorPickerEvent onPicker{get { return m_evnet; }set { m_evnet = value; }}
}
- 提供继承至UntiyEvent的事件类型并提供一个Color参数
- 监听该事件即可获取到颜色拾取器当前的颜色
- 该事件接口也会在在Inspector面板显示,可以通过拓展的方式实现监听
具体使用
- 代码监听
public class Program : MonoBehaviour
{public Image image = null;public ColorPicker Picker = null;private void Awake(){Picker = GameObject.Find("Canvas/ColorPicker").GetComponent<ColorPicker>();Picker.onPicker.AddListener(color =>{// 在颜色拾取变化时即可个Iamge组件赋值颜色image.color = color;});}
}
- Inspector面板监听
public class Program : MonoBehaviour
{public Image image = null;public void SetColor( Color color ){image.color = color;}
}
后续拓展
- 颜色拾取器的博客内容就更新到这里,但是颜色拾取器组件还有部分功能尚未实现,因为都是逻辑问题,所以博主会抽空优化代码并把残缺的部分补足。
- 后续的博文中会更新一些Unity讨论群中经常遇到的问题,比如ScrollRect优化(加上缓冲池),Iamge组件的拓展,实现PPT中各种进入、推出的效果甚至是翻书效果,还有如何实现全景照片,还有之前写好的条形图和折线图等,如果你觉得以上组件对你有帮助,关注我的博客,我会持续更新。
Unity自定义UI组件系列
- Unity自定义UI组件(八) 颜色拾取器(上)
- Unity自定义UI组件(七)渐变工具、渐变色图片、渐变遮罩
- Unity自定义UI组件(六)日历、日期拾取器
- Unity自定义组件之(五) 目录树 UITree
- Unity自定义UI组件(四)双击按钮、长按按钮
- Unity自定义UI组件(三)饼图篇
- Unity自定义UI组件(二)函数图篇(下)
- Unity自定义UI组件(一)函数图篇(上)
Unity框架解读系列
- [Unity]PureMVC框架解读(下)
- [Unity]PureMVC框架解读(上)
分享地址
- Github :https://github.com/ll4080333/UnityCodes
- CSDN : http://blog.csdn.net/qq_29579137
如果你想了解UGUI的更多拓展组件,欢迎关注我的博客,我会持续更新,支持一下我这个博客新手。如果以上文章对你有帮助,点个赞,让更多的人看到这篇文章,我们一起学习。如果有什么指点的地方欢迎在评论区留言,秒回复。
Unity自定义UI组件(九) 颜色拾取器(下)相关推荐
- Unity自定义UI组件(十一) 雷达图、属性图
前言 借用梦想世界宠物属性图 想必大家都在游戏中见过属性图用于展示多种属性的数值,可以较为直观的对比某种属性的缺陷或者是哪种属性有优势.在三维可视化领域也会遇到类似的属性对比,用属性图来展示最为合适. ...
- Unity自定义UI组件(六)日历、日期拾取器
前言 考虑到工业项目中可能会利用到类似日历的工具,就比如选取某个时间节点,所以我结合UGUI源码开发了日历工具和日期拾取器工具,简单易用,接口齐全,可中文显示,外观可自定义.只需要导入脚本,即可在Hi ...
- Unity自定义UI组件(七)渐变工具、渐变色图片、渐变遮罩
欢迎阅读Unity自定义UI组件(七)渐变工具.渐变色图片.渐变遮罩 前言 在Unity中UGUI只为我们提供了最为基础的Image和RawImage两种可展示图片的组件,但是这两种组件要展示一些特殊 ...
- Unity自定义UI组件(一)函数图篇(上)
Untiy自定义UI组件 ==转载标明出处== MaskableGraphic(可遮罩图形): MaskableGraphic是Unity中多种UI组件的父类,比如Image.Text等.Untiy官 ...
- 颜色拾取器color picker (javascript version)
颜色拾取器 216种web safe color的构造方法 var cl = ['00','33','66','99','CC','FF']; var clist = []; for( ...
- Android开发自定义UI组件
Android开发自定义UI组件实现红色小球跟随手指移动 要写实现自定义UI组件,要创建一个BallView类,继承View类,在BallView类中创建画笔,然后重写OnDraw()方法和OnTou ...
- Android自定义View之七色环颜色采集器: 续我未完的大学梦 !
Android自定义View之七色环颜色采集器:续我未完的大学梦!! 一.前言. 在大学期间,看到机智云开源的这个rgb灯,蛮好奇的,这么漂亮的颜色采集,并且可以同步到设备rbg灯颜色,甚是不解!这个 ...
- 【详细】Android入门到放弃篇-YES OR NO-》各种UI组件,布局管理器,单元Activity
问:达叔,你放弃了吗? 答:不,放弃是不可能的,丢了Android,你会心疼吗?如果别人把你丢掉,你是痛苦呢?还是痛苦呢?~ 引导语 有人说,爱上一个人是痛苦的,有人说,喜欢一个人是幸福的. 人与人之 ...
- Winform中实现颜色拾取器获取RGB与16进制颜色程序与源码分享
场景 效果 实现 关键代码 using System; using System.Collections.Generic; using System.ComponentModel; using Sys ...
- 在线颜色拾取器 - 资源篇
在线颜色拾取器 - 资源篇 点击访问资源: 在线颜色拾取器 截图示下:
最新文章
- 并发 IO多路复用 select 非asyncio
- Nginx proxy_cache 使用示例
- 必须要掌握的 InterruptedException 异常处理
- oracle的自动增长,Oracle实现id自动增长
- 分享一次 Java 内存泄漏的排查
- 笔记本触摸板滑动(双指滑动)太快怎么设置?
- JVM实战与原理---内存区域分配
- 前端笔记(1-20)
- 视觉slam学习笔记以及课后习题《第五讲特征点法视觉里程计》
- C++基础教程,基本的输入输出
- 51Talk2019战略升级,发布互动教学产品妖果AI
- 【技术贴】从51下载的网站代码asp源码怎么运行?怎么打开?
- Connection terminated as request was larger than XXX
- HLA RTI(Run-time Infrastructure)
- 工厂软件支持及测试是什么,软件工厂
- 综合项目 旅游网 【4.旅游线路名称查询-参数传递】
- pandas中如何提取DataFrame的某些列
- 微信小程序知识点(上)
- pythonista免费下载-pythonista 3ios
- 山东省有哪些计算机专业大学排名,山东人工智能专业大学排名