Unity终于在即将到来的4.6版本内集成了所见即所得的UI解决方案(视频)。事实上从近几个版本开始,Unity就在为这套系统作技术扩展,以保证最终能实现较理想的UI系统。本文试图经过初步的介绍和试用,让读者对这套系统有大致的了解,以便更进一步评估这套UI系统好很差用,适合用在什么项目。为了不坑挖太深,更进一步的试用和评估我将在《用uGUI开发自定义Toggle Slider控件》中进行论述。为论述方便,下文将这套New UI System简称为uGUI,而且以X-UI指代现有第三方UI插件。 html
(测试只针对Unity 4.6.0 beta 10,正式版可能会有所出入。目前Unity没提供文档,本人半桶水,欢迎群众在微博或Issues里吐槽!) git
Rect Transform继承自Transform,是uGUI相比X-UI最显著的区别[注1]。当你为Empty GameObject加入一个UI Component时,Transform会自动转换为Rect Transform。Rect Transform尽可能整合了X-UI常见的anchor(相对父物体的锚点), pivot(中点), stretch(拉伸)等属性。值得一提的是,这里的anchor是Rect而非Vector2,由于它不只用于偏移,并且用于缩放。点击Rect Transform上的准心图标,还能在弹出的Anchor Presets面板中对其进行快速设置。 github
这个面板仍是不够直观,咱们能够把它当作一张表,上面四个图标用于设置列,左边四个图标用于设置行,也能够直接点击里面的16个图标同时设置行和列。强大的地方是,按住shift时能同时设置pivot,这时能发现控件虽然不动但position已经在改变。若是按住alt,则设置anchor的同时设置position。若是shift和alt同时按住,那么你就能同时设置anchor, pivot和position。这个操做方式比起X-UI,真的高明不少,对多分辨率适配颇有帮助。 算法
除此以外,Rect Transform还提供了Blueprint和Lock Rect选项,前者用于对旋转过的元素进行定位,后者听说明是能在设置anchor时保持位置不变,暂时没搞明白。 canvas
uGUI能够直接在Hierarchy面板中上下拖拽来对渲染进行排序(支持程序控制),越上面的UI会越先被渲染,相比X-UI的global depth排序,这样的拖拽设计很讨好用户。同时在结构上则和ex2D采用的local depth相似,这样GO只和同级其它GO进行排序,开发组件会很方便。须要注意的是,这里排序只是相对UI而言,其它3D物体仍是按原先的次序渲染,而且UI老是渲染在3D物体上面。这就致使你不能像用ex2D那样直接将粒子系统插入到两个UI之间。 缓存
这种无需填写depth值的排序方式,容易致使没有手工作sprite packing的free版用户遇到draw call增长。由于全部物体的depth都是自动设置的,Unity保证了每一个物体的depth都是惟一的。这时假设你有一个格子控件,每一个控件用到了两个Sprite,但你并无把Sprite都拼到同一张贴图上。因而你每复制一个新的格子出来,draw call就会增长2个,由于Unity会以格子为单位依次绘制。pro用户因为有sprite packing机制,不用担忧这个问题。(这种状况在ex2D里,是以默认提供"unordered"的渲染方式来解决的,这也是NGUI的默认作法。在这种状况下ex2D会优先以相同depth的相同Sprite为单位绘制,所以不论有多少个格子,draw call都是2个。除非你就是但愿以格子为单位进行渲染[注6],那么你能够在ex2D里设置渲染方式为"ordered",或者在NGUI里给每一个格子设置不一样的depth。 架构
uGUI自带了以上控件,其中Image用于显示Sprite,Raw Image用于显示Texture,Image Mask和Rect Mask用于clipping。全部控件都是MonoBehaviour,能够直接从Inspector里拖到其它GameObject上。 框架
uGUI用Image控件显示图片,图片就是一个Sprite,这意味着Pro用户不用再制做atlas了,相比X-UI是个大进步,Free用户同样能够手动作Packing。Image提供了Simple, Sliced, Tiled, Filled四种效果,和X-UI保持一致。 ide
uGUI里,Button控件由两个GameObject组成,一个包含Image, Button等Component,一个包含Text等Component。这样设计很组件化,惟一的问题是当用户想修改Button时,容易不当心选中Label或其它实体。 工具
Button Component主要执行Transition和事件两个操做。
uGUI控件每每只提供一个自带事件,要响应更多基本事件的话,须要添加Event Trigger组件。Event Trigger包含如下事件:
能够在Event Trigger中Add多个事件,每一个事件均可以添加多个命令,用法和控件自带事件一致。
每一个Canvas都有一个Graphic Raycaster,用于获取用户选中的uGUI控件。多个Canvas之间经过设置Graphic Raycaster的priority来设置事件响应的前后次序。当Canvas采用World Space或Camera Space时,Graphic Raycaster的Block选项能够用来设置遮挡目标。
建立uGUI控件后,Unity会同时建立一个[注4]叫EventSystem的GameObject,用于控制各种事件。能够看到Unity自带了两个Input Module,一个用于响应标准输入,一个用于响应触摸操做。Input Module封装了对Input模块的调用,根据用户操做触发各Event Trigger。理论上咱们能够编写本身的Input Module,用来封装各类外部设备的输入,只要加入Event System所在的GameObject就行。
Event System组件则统一管理多个Input Module和各类Raycaster。它每一帧调用多个Input Module处理用户操做,也负责调用多个Raycaster用于获取用户点击的uGUI控件以及2D和3D物体。
2D渲染分两大类,一类是单纯的Sprite绘制,用于渲染场景、角色、粒子等,另外一类是UI绘制。Unity将这两类需求划分红了SpriteRenderer和uGUI两部分,前者由Transform + SpriteRenderer实现,后者由Rect Transform + CanvasRenderer + UI控件 + Canvas[注2]实现,这样的两套相对独立的机制比起X-UI的UI控件继承自SpriteRenderer更为合理。由于在2D游戏里SpriteRenderer只须要关心最基本的面片渲染,注重效率,而UI注重各种变换、对齐、操做、动画,还经常须要Resize VBO。若是SpriteRenderer在设计上须要兼顾UI,就会像X-UI那样设计得太过复杂,在用户体验和性能上都很很差。
这里咱们探讨一下uGUI的渲染机制,当咱们渲染多个使用相同Sprite的控件时,并没发生dynamic batching,可是drawcall也没有上升。这就说明Unity在内部使用了专门的一套batching机制,把多个控件的VBO事先合并成了一个。也就是说CanvasRenderer不负责实际渲染,而是由Canvas批量渲染多个CanvasRenderer,这和部分X-UI采用的作法一致。这样单独batch的设计有可能使得性能比SpriteRenderer好,也可能致使性能更差。性能会更好的状况在ex2D里已经证明了,主要缘由是这样能更好的平衡CPU和GPU负载,而且能作到更优化的batching算法。性能更差的状况,在去年旧版的NGUI测试时也遇到了,根本缘由仍是优化不到位致使的(不是贬低,不一样工具的取舍和面向市场都不一样)。而Unity的 SpriteRenderer在手机上的渲染跑分是和ex2D持平的,CanvasRenderer又比SpriteRenderer快[注3],所以uGUI的性能不用担忧。因为目前没有Mac版本,我会在正式版发布后进行一次手机跑分测试。
uGUI功能完善,操做简洁,很接地气。能够说uGUI是相对X-UI的全面升级,总体架构更为严谨,实现更为清晰。依托4.5的Module Manager,uGUI以Package的形式提供,也能得到快速的升级[注5]。做为ex2D v2.0开发者之一,我很看好它未来的发展,uGUI将在大多数场合取代X-UI。
初步感觉: