Unity4.6新UI系统初探(uGUI)

一、引言

Unity终于在即将到来的4.6版本内集成了所见即所得的UI解决方案(视频)。事实上从近几个版本开始,Unity就在为这套系统做技术扩展,以保证最终能实现较理想的UI系统。本文试图通过初步的介绍和试用,让读者对这套系统有大体的了解,以便更进一步评估这套UI系统好不好用,适合用在什么项目。为了避免坑挖太深,更进一步的试用和评估我将在《用uGUI开发自定义Toggle Slider控件》中进行论述。为论述方便,下文将这套New UI System简称为uGUI,并且以X-UI指代现有第三方UI插件。

(测试只针对Unity 4.6.0 beta 10,正式版可能会有所出入。目前Unity没提供文档,本人半桶水,欢迎群众在微博或Issues里吐槽!)

二、Rect Transform

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面板中对其进行快速设置。

这个面板还是不够直观,我们可以把它看成一张表,上面四个图标用于设置列,左边四个图标用于设置行,也可以直接点击里面的16个图标同时设置行和列。强大的地方是,按住shift时能同时设置pivot,这时能发现控件虽然不动但position已经在改变。如果按住alt,则设置anchor的同时设置position。如果shift和alt同时按住,那么你就能同时设置anchor, pivot和position。这个操作方式比起X-UI,真的高明很多,对多分辨率适配很有帮助。

除此之外,Rect Transform还提供了Blueprint和Lock Rect选项,前者用于对旋转过的元素进行定位,后者据说明是能在设置anchor时保持位置不变,暂时没搞明白。

三、排序

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上。

4.1 Image

uGUI用Image控件显示图片,图片就是一个Sprite,这意味着Pro用户不用再制作atlas了,相比X-UI是个大进步,Free用户一样可以手动做Packing。Image提供了Simple, Sliced, Tiled, Filled四种效果,和X-UI保持一致。

4.2 Button

uGUI里,Button控件由两个GameObject组成,一个包含Image, Button等Component,一个包含Text等Component。这样设计很组件化,唯一的问题是当用户想修改Button时,容易不小心选中Label或其它实体。

Button Component主要执行Transition和事件两个操作。

  • Transition可选择改变颜色、更换贴图或自定义动画,使用起来简单方便,也能利用动画定义更丰富的表现。我会再写一篇文章演示Button的Transition。

  • 事件也是所见即所得的,在OnClick里面可以添加多个命令,命令可以选择对应的目标、操作和参数。用法简单,有需要也可以换程序控制。
    • 目标可以是任意Object,例如其它GameObject或者Project里的Asset

    • 操作可以是需要设置的参数或调用的方法
    • 参数分成Dynamic和Static,Dynamic能将控件的参数单向绑定到目标参数,Static则将目标参数设置成预设值。按钮没有Dynamic参数,Toggle, Slider等控件才有。

五、事件

5.1 Event Trigger

uGUI控件往往只提供一个自带事件,要响应更多基本事件的话,需要添加Event Trigger组件。Event Trigger包含以下事件:

  • PointerEnter, PointerExit, PointerDown, PointerUp, PointerClick

  • Move, Drag, Drop, Scroll
  • KeyDown, KeyUp, Select, Deselect

可以在Event Trigger中Add多个事件,每个事件都可以添加多个命令,用法和控件自带事件一致。

5.2 Graphic Raycaster

每个Canvas都有一个Graphic Raycaster,用于获取用户选中的uGUI控件。多个Canvas之间通过设置Graphic Raycaster的priority来设置事件响应的先后次序。当Canvas采用World Space或Camera Space时,Graphic Raycaster的Block选项可以用来设置遮挡目标。

5.3 Event System

创建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将这两类需求划分成了SpriteRendereruGUI两部分,前者由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。

初步感受:

7.1 亮点

  • RectTransform

  • Event/单向数据绑定
  • 直接在Hierarchy中排序
  • Pro用户可用Sprite的动态拼图,无需手工拼图

7.2 不足

7.3 小遗憾

  • Anchor Presets面板还不够直观。

  • 用户想修改Button时,很容易修改到Label。
  • 当Hierarchy面板内的目标节点展开子节点后,无法将其它节点直接拖动到目标的正下方。

7.4 小问题

  • Input组件对方向键的支持有问题。

  • Game View dock到主窗口后,top定位有误,把toolbar的高度也算进去了。

八、附注

  1. 我们在其它平台上开发类 Entity-Component框架时,讨论过Unity为什么不在底层对transform做特殊处理,以避免插件作者手工缓存transform来优化query transform引起的开销,甚至是将transform直接整合进GameObject。原因是现在的transform是3D的,将来完全可能推出 2D Transform。所以Unity在之前的版本里一直保留着transform的独立性。

  2. 我不能完全肯定一定是Canvas,但通过Canvas和CanvasRenderer的接口来看,这个可能性很大。
  3. 基于更好的平衡CPU和GPU负载 + 更优化的batching算法,以Unity的实力CanvasRenderer超越SpriteRenderer问题不大。而且如果性能不会提升,uGUI只要像2D Toolkit那样给每个控件直接添加MeshRenderer,也就是说uGUI直接用已有的SpriteRenderer就好,不太可能加入新的CanvasRenderer性能反而更慢。
  4. Unity允许多个Event System同时存在,但同一时刻只有一个能够生效。
  5. uGUI的控件、Event等模块以包的形式提供,位于程序目录下的%UNITY%\Editor\Data\UnityExtensions\Unity\GUISystem\4.6.0,Unity 提供了两个运行时版本的DLL,分别用于创作和发布。区别主要是发布版不含一些Editor中才用得到的代码。由于DLL没办法通过预编译符号来进行条件编译,因此Unity使用这种方式进行权衡,用户发布时无需手工切换DLL版本,满足了闭源,又兼顾了执行效率。这样就甩开了第三方插件几条街,很多插件在这个问题上不是牺牲性能就是无奈开源。
  6. 有时还是会需要以格子为单位渲染,例如当格子之间需要重合,这种需求在UI里不常见。

本文作者:Jare @ 梦加网络

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

时间: 2024-12-25 06:57:59

Unity4.6新UI系统初探(uGUI)的相关文章

(十)Unity5.0新特性------新UI系统实战

原文 Unity New GUI Tutorial – Part 1 Unity New GUI Tutorial- Part 2 Unity New GUI Tutorial – Part 3 大家可以看看他的游戏源代码,然后了解一下新UI的使用.  介绍的很详细: 需要指出的 UI的动画都是使用 Animator\Animation组件实现,在实际的项目开发中,会使用Dotween\  Dftween这些补间动画插件来实现.   用代码通知,更加灵活. 但是使用 Animator\Anima

全面理解 Unity UI 系统

[狗刨学习网] 随着 Unity 4.6 发布,新 UI 系统终于与大家见面了. RectTransform Unity UI 系统使用 RectTransform 实现基本的布局和层次控制.RectTransform 继承于 Transform,所以 Transform 的所有特征 RectTransform 同样拥有.在 Transform 基础上,RectTransform 增加了 轴心(pivot).锚点(实际上是用 anchorMin.anchorMax 两个点定义的矩形区域).和 尺

理解和使用 Unity UI 系统

随着 Unity 4.6 发布,新 UI 系统终于与大家见面了.这篇文章将不会介绍如何使用按钮.滚动条之类的UI控件,这些内容可以参考Unity Manual:这篇文章的重点是,如何理解 UI 系统的设计,以便更好的在实际中使用.自定义和扩展. EventSystem 如果你使用 UI 系统,那么 EventSystem 对象会自动创建.这个对象负责监听用户输入.默认情况下,在电脑上可以使用键盘和鼠标输入,在移动设备上可以使用触摸输入.但是如果你要为surface这样的设备开发,你也可以同时启用

Unity3D 4.6 新的UI系统

在Unity3D 4.6版本中,终于增加了新的UI系统.虽然从功能,效果等方面来讲,跟NGUI还有一定的差距,但NGUI毕竟是收费插件,对于游戏商用来说有一定的制约. 下面我们来看看,Unity3D 4.6中新的UI系统吧. 如上图所示,我们可以看到在GameObject菜单中,已将3D Object,2D Object和UI分类了. UI中,我们可以看到Panel,Button,Text,Image,RawImage,Slider,Scrollbar,Toggle,InputField,Can

Unity3D 4.6 新的UI系统啊

在Unity3D 4.6版本中,终于增加了新的UI系统.虽然从功能,效果等方面来讲,跟NGUI还有一定的差距,但NGUI毕竟是收费插件,对于游戏商用来说有一定的制约. 下面我们来看看,Unity3D 4.6中新的UI系统吧. http://travel.tianya.cn/travelPlan/showPlan?planId=8413297 http://travel.tianya.cn/travelPlan/showPlan?planId=8413298 http://travel.tiany

[Unity3D]Unity4全新的动画系统Mecanim

Unity4.X添加一个新的动画系统,以取代原有的3.X旧的动画系统,全新的动画系统Mecanim是官方推荐,它使我们能够写更少的代码实现连续动画. 效果图 Unity3.X中动画系统播放动画 使用播放play()或淡入淡出播放CrossFade() 比如: animation.Play("name"); animation.CrossFade("name"); 也能够做成队列动画.然后播放,比如: animation.PlayQueued("name&q

Unity 新UI事件系统(EventSystem) Demo

新的UI系统消息传递被全新设计,该系统用MonoBehaviour 来实现自定义的接口,以便可以接受来自消息系统的回调.当一个对象被消息的执行指定,那么这个对象的所有实现了自定义接口的脚本将被通知,指定的方法将被执行. 1.定义一个接口ICustomMessageTarget继承IEventSystemHandler, 这样当发送此类型消息时,实现此接口的脚本所在的对象将会被通知. using UnityEngine; using UnityEngine.EventSystems; using

Unity3d 4.0新动画系统Mecanim用法(二)

上一篇,我们初步了解了一下Mecanim的部分很基础的类容,我以一个疑问的形式结尾.这次我来揭晓此问题的答案,其实很简单,上次的警告如下: 4.0新动画系统Mecanim用法(二)"> 警告的大概意思是:用在Animator Controller中的Animation clips需要有在检视面板中被设置了Muscle(肌肉)的这个步骤. 我的英文很烂,但我可以知道这句话的含义,就是我们的用到的这个Animation Clip必须是已经产生了Avatar的模型中的Animation Clip

小程序新零售系统能给企业带来哪些效益

小程序新零售系统怎么帮助企业结合O2O 1.小程序新零售系统的核心模式,新零售=大数据 线上交易平台 线下的体验平台.支付.最有效的物流整合, 线上与线下渠道的打通,以大数据作为指引,以支付和物流作为完成闭环的一节,这五步,构成了未来新零售的骨骼. 2.是消费者的诉求驱动了生产链.刘兴波并不觉得销售传统如人们所说的被颠覆了,反而只是市场的一种进步,是消费习惯和销售形态之间的共同进步.人们逐渐迁移至移动端,更加数字化,产生了更强的主观意识,而"现代人"自主的生活方式探寻出了新零售的发展方