一、前言

写完《Unity4.6新UI系统初探》后,我模仿手机上的UI分别用uGuiNGUI做了一个仅用作演示的ToggleSlider,我认为这个小小的控件已能体现自定义控件的开发过程。由于手头上没有mac版,暂时未能真机测试,PC上的效果如下:

二、制作过程

完整工程托管于github,分为uGui和NGUI两个project。考虑到版权问题,工程里不含NGUI,同学们需自行将NGUI导进工程。NGUI需要Unity 4.5,uGui需要Unity 4.6。

三、功能点

  • 滑块可以拖动,从一边拖到另一边将改变控件值。
  • 用户停止操作时,滑块如果居中,会自动滑向最近的一边。
  • 点击滑块或整个控件,控件值将被改变,滑块自动滑向另一边。
  • 控件值被其它脚本修改时,滑块自动滑向另一边。
  • 滑块移动的过程中,如果值发生变化,滑块会以当前位置为起点滑回去。

下面以uGui为例简述制作方法,NGUI的方法也差不多,两者的区别可参考下文[和NGUI对比]。

四、Hierarchy

上图是用uGui制作好的层级结构。其中,

  • Canvas负责渲染UI。

    • Padding没什么用,只是画了一个边框。

      • Toggle Slider是控件的父物体。

        • BackgroundAndMask使用ImageMask组件作为SymbolOff的遮罩,同时渲染灰色底图。

          • SymbolOff是灰色的twitter小鸟,坐标受动画控制。
        • Background_On使用Image组件渲染蓝色高亮底图,Color.alpha受动画控制。
        • BackgroundMaskOnly使用ImageMask组件作为SymbolOn的遮罩,并不渲染。
          • SymbolOn是蓝色的twitter小鸟,坐标受动画控制。(不用Background_On作遮罩是因为蓝色底图的边缘是半透明的。)
        • Handle是正方形滑块,坐标受动画控制。
      • Current Value是下面那个可选框,用于测试Toggle Slider。
  • EventSystem可参考上篇文章。

五、Toggle Slider GO

Toggle Slider对象包含的Toggle Slider组件是唯一一个直接和控件有关的脚本。代码可在github查阅,编写起来很简单。

六、Animation

所有效果都使用Animation组件实现,全部用动画是为了偷懒,毕竟效果怎么实现都可以,这里仅作演示。动画包含四条曲线,分别用于控制两只twitter小鸟、蓝色背景透明度和滑块左右移动。这里简单提几个要点。

  • 动画的反向播放只需要将AnimationState.speed设为-1。
  • 拖拽滑块时,动画暂停,根据鼠标位移逐帧设置动画时间,然后Sample动画。拖拽停止时恢复动画。
  • 在动画里改变透明度时,Image组件不会自动更新,需要添加一个ColorWatcher组件,自己触发Image.color的setter。
  • 动画设为ClampForever,因为Once无法在AnimationState中保留最后一帧的状态。

七、Event

事件使用两个Event Trigger组件进行响应。一个在Toggle Slider对象里,负责响应OnPointerUp,实现当点击控件时,调用ToggleSlider.Toggle()。另一个在Handle对象里 (如图),负责响应Drag事件,实现当拖动时调用ToggleSlider.OnDrag()。

在此遇到了一个蛋疼的问题,Event Trigger的Drop事件在这里无效,又没有单独的DragEnd事件,因此只好在Handle上增加OnPointerUp事件来监听拖动是否结束。如此一来,Handle的OnPointerUp就会把上层控件的OnPointerUp事件拦截掉……我希望Unity能提供类似冒泡的机制,这样一来我就能在Handle上添加一个脚本,只对拖拽结束进行响应,如果是单击事件就冒泡到上层控件进行处理。

最终我的做法是,Handle的OnPointerUp事件也由ToggleSlider.OnPointerUp()响应,OnPointerUp内部通过dragging标记来判断是拖动结束还是单击。

八、不足

  • Event Trigger没有冒泡机制,子控件如果不处理事件,没办法抛给父控件处理。
  • ImageMask没能选择alpha threshold。

九、存在的Bug

这段时间的测试遇到过几个问题:

  • 经常警告"Material uGUI/Stencil Mask doesn't have stencil ... SendWillRenderCanvases()"。有时会导致Image无法显示,要换过一次Sprite之后才正常。
  • 两个Hierarchy内平级并且相邻的ImageMask,都选中DrawImage,结果上面一个会挡住下面一个。需要在两个中间插入一包含CanvasRenderer的GO才行,GO可以deactivated。
  • 当我制作NGUI版本时,从uGui复制了一份出来再做修改。做到一半时我发现Hierarchy多了一个不含子物体的副本,当我选中控件时副本会同时被选中。于是我重启Unity,发现Unity已经死锁无法关闭,强制结束后项目损坏,只要一打开就crash,手动删除scene后才恢复正常。估计是我在继承树上混用NGUI/uGui,或者uGui未剔除干净引起的,已向官方反馈。

十、和NGUI对比

作为对比,我也用NGUI的测试版(3.6.4b)做了一样的demo,花了不少时间。uGui的事件问题也在NGUI里遇到了,甚至更严重,此外还有其它问题。

  • NGUI的padding设置挺繁琐的,uGui只要Rect Transform点下stretch,Left/Top/Right/Bottom全写20就行。

    添加padding时,我试着创建一个UIWidget,然后设置Anchors为Unified,然后依次设置Left/Top/Right/Bottom为Target's Left/Top/Right/Bottom,然后数值填入20/-20/20/-20才行。

  • NGUI添加Toggle有点复杂,uGui只要Hierarchy里Create一个就完事了。

    创建调试用的Current Value时,找不到NGUI的Toggle组件,后来输入名称才找到,但还是不太会用。后来想到Examples里有toggle的prefab可以用,拖进Scene后对比了下发现NGUI的实现方式比uGui复杂了些,难以手工创建出来。看来Project里要把NGUI这些常见库都备好才行。

  • NGUI设置Anchor有点失败

    将Toggle的prefab实例化到scene里后,设置了很久都没能让Toggle自动居中。难道这个Toggle的尺寸如果是动态的,NGUI就没办法自动居中?或许是我对NGUI还不是很了解,最终我只能根据Toggle宽度算出坐标偏移。

  • NGUI没有Image Mask

    所以这个版本没能加入那两个twitter的logo。这个怪不了NGUI,因为Unity的free版不提供访问stencil buffer的功能,因此第三方UI插件没办法实现比较好的clipping机制。

  • NGUI的UIEventTrigger无法获得事件参数

    UIEventTrigger和uGui的EventTrigger类似,能够触发远程方法。但是NGUI不能传入动态事件参数,虽然能用 UIEventTrigger.current获得当前事件,可UIEventTrigger对象其实没定义任何参数。要获得参数,只能自己写一个带有 OnDrag的组件,附加到GameObject上,或者使用UIEventListener,总之就不支持可视化编辑,只能用代码动态绑定事件。

  • NGUI的UIEventListener无法响应停止拖动事件

    为了解决前一个问题,我使用了UIEventListener来获得拖动参数。然而当我想响应停止拖动事件时,我发现还是要用回UIEventTrigger才行。如果用户不希望混用这两个脚本,那么只能自己写一个脚本。

十一、小结

uGui功能和用户体验方面都做的不错,是我看到过最贴近Unity风格的UI系统。稳定性方面有小问题,不过作为测试版可以理解,已经超过了我的预期(之前以为会和4.0的刚推出Mecanim一样bug一堆)。

性能方面,两个工程我都实现了相同的PackedBenchMark场景,里面各包含了30个ToggleSlider,为了公平uGUI版本去掉了所有ImageMask,两边实测drawcall一致。从帧率上看在编辑器下NGUI性能优于uGUI大约20%!估计是因为NGUI在最近几个版本中完善了batching机制,而uGUI并没有采用前一篇文章所说的"更优的"batch算法,而是把batching粗暴的交给了显卡驱动完成。如果有pro版的话使用profiler查看一下两边的CPU/GPU占用就能知道答案。

文献资料

本文作者:Jare @ 梦加网络

本文转载自https://github.com/jaredoc/unity-ugui/tree/master/toggle_demo

用uGUI开发自定义Toggle Slider控件相关推荐

  1. SAP UI5 应用开发教程之三十二 - 如何创建一个自定义 SAP UI5 控件试读版

    一套适合 SAP UI5 初学者循序渐进的学习教程 教程目录 SAP UI5 本地开发环境的搭建 SAP UI5 应用开发教程之一:Hello World SAP UI5 应用开发教程之二:SAP U ...

  2. 基于WP7开发的Silverlight常用控件详解

    Silverlight是一个跨浏览器.跨客户平台的技术,能够设计.开发和发布有多媒体体验与富交互(RIA,Rich Interface Application)的网络交互程序. 针对Windows P ...

  3. VC2005从开发MFC ActiveX ocx控件到发布到.net网站的全部过程

    VC2005从开发MFC ActiveX ocx控件到发布到.net网站的全部过程 开篇语:最近在弄ocx控件发布到asp.net网站上使用,就是用户在使用过程中,自动下载安装ocx控件.(此文章也是 ...

  4. Angular19 自定义表单控件

    1 需求 当开发者需要一个特定的表单控件时就需要自己开发一个和默认提供的表单控件用法相似的控件来作为表单控件:自定义的表单控件必须考虑模型和视图之间的数据怎么进行交互 2 官方文档 -> 点击前 ...

  5. C# Winform 通过FlowLayoutPanel及自定义的编辑控件,实现快速构建C/S版的编辑表单页面...

    个人理解,开发应用程序的目的,不论是B/S或是C/S结构类型,无非就是实现可供用户进行查.增.改.删,其中查询用到最多,开发设计的场景也最为复杂,包括但不限于:表格记录查询.报表查询.导出文件查询等等 ...

  6. C#开发学习——web服务器端控件

    Asp.net在客户端开发和web开发所用到的控件还是有很大的差别的,而且Web开发的界面是在浏览器中显示的,所以控件的设计都和前边学习HTML设计有联系,没有客户端开发那么简单,不过我们可以通过专门 ...

  7. iOS开发UI篇—UITableview控件基本使用

    iOS开发UI篇-UITableview控件基本使用 一.一个简单的英雄展示程序 NJHero.h文件代码(字典转模型) 1 #import <Foundation/Foundation.h&g ...

  8. 继续聊WPF——Slider控件

    Slider控件,讲行通俗一点就是我们很常见的滑块,控件的外观上显示一系例刻度值,并存在一个可以被拖动的滑块,用户可以通过拖动滑块来控制控件的值. 如下图所示,是Windows系统的音量调节滑块. 下 ...

  9. iOS开发UI篇—UITableview控件使用小结

    iOS开发UI篇-UITableview控件使用小结 一.UITableview的使用步骤 UITableview的使用就只有简单的三个步骤: 1.告诉一共有多少组数据 方法:- (NSInteger ...

最新文章

  1. glib 2.0 arm linux,glib源码安装使用方法
  2. 思考问题:Python这两段等效代码内存占用为什么差别那么大?
  3. 【Mac】Mac下安装MySQL优化工具 percona-toolkit 报错 Error: Failed to download resource openssl@1.1
  4. 6-1 健壮性与正确性
  5. 百度发布AI芯片“昆仑”;李笑来脏话录音曝光;Facebook再现新漏洞 | CSDN 极客头条...
  6. ubuntu下安装g++
  7. .NET(C#):觉察XML反序列化中的未知节点
  8. C语言程序NS流程图生成器,请各位大神帮个忙,画个NS流程图,,急!!!
  9. Windows Server 2016 安装IIS
  10. powerdesigner 16.5 Could not Initialize JavaVM!
  11. 对称加密算法原理简介
  12. 六月福师计算机应用基础在线作业,19春福师《计算机应用基础》在线作业一答案满分...
  13. 《数据结构(C语言版)》严蔚敏代码实现———顺序表
  14. 埃及分数c 语言程序,C语言将真分数分解为埃及分数
  15. 【转】一起做RGB-D SLAM (1)
  16. Linux进阶 | 2万字总结最详细的Docker的安装、底层隔离机制和简单使用!建议收藏,持续更新❤
  17. vsftp 多用户不同访问权限配置
  18. Unity中的宏定义
  19. Python 自动化办公
  20. 名编辑电子杂志大师教程 | 设置电子杂志的高宽比例

热门文章

  1. 搜集侠采集织梦系统模板
  2. 最全Spring Boot2.x系列Config配置集成篇-1参数配置
  3. linux上使用ASP
  4. Python3.0 新特性
  5. 人工智障学习笔记——机器学习(5)朴素贝叶斯
  6. Ubuntu14.04安装ROS
  7. C++——构造高度平衡的BST,并按层序输出
  8. C/C++——一个因为unsigned引发的大问题
  9. 【Latex】分数写法区别
  10. 无透镜成像相关资料汇总