《Unity3D高级编程之进阶主程》第四章,UI(二) - UGUI的原理及组件使用详解

前文回顾 UI(一)

    前文对NGUI和UGUI进行了比较,讲述了如何选择UI系统作为项目的UI框架。

这篇我们来讲讲,UGUI的原理,以及UGUI的组件使用详解。

===

UGUI的初级和高级使用详解

首先我们来介绍下ugui的运作机制。

UGUI是在3D网格下建立起来的UI系统,它的每个可显示的元素都是以3D模型面片的形式来构建的,在UI被构建时,UGUI首先要做的事就是构建网格。

也就是说,在Unity3D制作一个图元素,或者一个按钮,或者一个背景时,都会先构建一个方形网格,再将图片放入网格中,就相当于一个3D模型一样,一个网格绑定一个材质球,材质球里放了图片。

如果每个元素,生成一个模型,绑定一个材质球,切入一张图片的话,UI上成千上百个元素就会拥有成千上百个材质球,以及成千上百张图。

这样会造成引擎需要每次渲染时都需要读取成千上百张图,对每个材质球和网格都进行渲染,这会导致性能开销过大,性能急剧下降。

于是UGUI做了优化,将一部分相同类型的图片都集合起来合成一个张图,然后将拥有相同图片相同shader的材质球合并成一个材质球,并且把分散开的模型网格也一起合并了,这样就生成了几个大网格和几个材质球,以及少许整张的图集。节省了很多材质球,图片,网格的渲染,UI的效率更高了很多,游戏在进行时才会顺畅。

不是所有的网格和材质球都合并成一个,只有相同的图集和相同的材质球参数才能合并网格,而且在当UI中的元素变动时,也同样需要做拆分网格和重新合并网格的操作。

在Unity3D中各类UI系统中,性能优劣差距就在这里拉开了,哪个系统能合并得更好,哪个系统能更多的减少合并的次数,以及在合并时是否能有更高的效率,成了拉开差距的关键.

因为这些合并和拆分的操作会消耗很多CPU,UI系统要做的就是尽一切可能节省些CPU消耗,把尽量多的剩余CPU让给项目逻辑。

下面我们来主要介绍下UGUI的核心组件。

核心组件Canvas

    Canvas,我们暂且叫它画布。Canvas就相当于一张画画时铺在上边的画板,我们把各类元素放在画布上后,Canvas要做的事情就是合并这些元素。

    Canvas上的参数包括Render Mode 渲染模式,你可以选择不以Camera为基准的Overlay模式,或者以Camera为基准的Screen Camera模式,也可以选择3D直接坐标为基准的World Space模式。三者根据的使用区域不同而不同。

    Overlay模式主要用在纯UI的区域内,例如我们不想使用Camera排序,而想用Sort order这个参数排序时可以使用,Sort order参数的值越大,越靠前渲染。如果这个模式下,加入一些非UGUI的物体时,会使得排序混乱。

    Sceen Camera模式,相对比较通用一点,他依赖Camera,所以需要创建一个矩形的Camera来进行绑定,渲染依靠的是于他绑定的Camera。

    在当非UGUI元素加入到UI中时,Screen Camera模式更加具有优势。
    在对UI进行排序时,可以通过与Camera的距离来进行绑定,也可以通过Order in layer这个参数进行排序,这样在开发和调试期间更加形象化。

    World Space模式,主要用于当UI物体放在3D世界中时用的,比如,一个大的场景中,需要将一张标志图放在一个石块头上,这时就需要World Space模式。

    他需要绑定一个透视(Perspective)的Camera,当UI物体在这个Camera视野中时,就相当于渲染了一个普通的3D面片的效果,只不过Canvas也对这些3D场景里的UI进行了合并优化处理。
Canvas Scaler
    这是个缩放比例组件,用来指定画布中元素的比例大小。

    有简单指定比例大小的Constant Pixel Size模式,也有Scale With Screen Size以屏幕为基准的自动适配比例大小,或者Constant Physical Size以物理大小为基准的适配规则。

    注,在手游项目里,通常使用以屏幕为基准的自动适配比例大小的Scale With Screen Size选项。
Graphic Raycaster
    输入事件与图形的碰撞测试组件,他检测着画布下的所有组件,是否与输入事件的射线碰撞,是否需要将碰撞的组件进行相应。

    你可以设置成完全忽略输入事件,或者阻止对某些layers进行事件相应。
EventTrigger
    输入事件触发器,与此脚本绑定的UI物体,都可以接受到输入事件。

    比如(鼠标,手指)按下,弹起,点击,开始拖动,拖动中,结束拖动,鼠标滚动事件等。

    有了他,我们就可以对需要响应手指触摸或鼠标的UI进行绑定了。
Image,RawImage
    这两个是UI里的主要部件,都是对图片的展示部件,图片,图集,图元,通过Image和RawImage可以展示在屏幕上。

    两者的区别是Image仅能展示图集中的图元,而RawImage仅能展示单张图片。通常我们会将小块的图片,打成图集来展示,这样更节省性能也更节省内存。

    但是,当遇到大块的图片时却不是这样了,因为太大,打成图集会造成图集不够用,或者说会图集的空间利用效率太低,所以用单独分出来自己独立展示。
Mask,RectMask2D
    遮挡组件,用来将其子节点下的区域外的内容遮挡。

    在上下滚动的菜单栏里用的会用到,因为我们需要将区域外的元素内容进行不显示操作。

    Mask和RectMask2D区别是,RectMask2D的效率比Mask更高,可以节省更多的drawcall,但是限制条件是RectMask2D只能用于2D上的展示。
其他组件
    大部分逻辑组件都是可以重写的,

    比如按钮组件Button,切换组件Toggle,滚动条组件ScrollBar,滑动组件Slider,下拉框组件DropDown,视图组件ScrollView,都是可以用Image,Mask等几个核心组件组合自己重写的。

    为什么要重写?因为很多时候项目里的需求更多样化,而且也需要足够的可控性,自己写的可以修改特殊需求和特殊逻辑,比原生态的组件好用的多。

    所以通常项目中,都会重写一些组件来用来自己项目使用,也有一些人总结了这些组件的经验,写了些比较好用的组件开源在Github上。

感谢您的耐心阅读

Thanks for your reading

  • 版权申明

    本文为博主原创文章,未经允许不得转载:

    《Unity3D高级编程之进阶主程》第四章,UI(二) - UGUI的原理及组件使用详解

    Copyright attention

    Please don't reprint without authorize.

  • 微信公众号