Unity3D学习笔记之uGUI(6):Auto Layout简述

发表于2017-02-24
评论0 3k浏览

  Auto Layout组件应用比较广泛的是界面系统的布局,可能有些开发者就会好奇Unity3D uGUI中的Auto Layout在时间项目中的应用,为此下面就给大家详细介绍下Auto Layout组件,不清楚的可以看一看。


6Auto Layout

         RectTransform布局系统足够灵活来应付各种布局需求,并且允许自由摆放各类元素。然而某些情况下需要结构化配置。

         自动布局系统(Auto Layout System)提供嵌套布局群组,诸如Horizontal GroupsVertical Groups以及Grids。它还可以根据所包含的内容来自动调整大小。例如一个按钮会动态增加边距来适应按钮上的文本内容。

         自动布局系统基于Rect Transform布局系统,适用于部分或全部元素。

 

6.1 Understanding Layout Elements

         自动布局系统基于布局元素(Layout Elements)和布局控制器(Layout Controllers)这两个概念。布局元素就是一个含有Rect Transform和其他可选组件的GameObject。布局元素知道自身尺寸应该是多少。然而布局元素并不会直接设置自身尺寸,而是交由诸如布局控制器的其他组件来设置,这样根据足够信息来计算它的尺寸应该是多大。

         一个布局元素有如下属性:

         1Minimum width:最小宽度

         2Minimum height:最小高度

         3Preferred width:建议宽度

         4Preferred height:建议高度

         5Flexible width:灵活宽度

         6Flexible height:灵活高度

         布局控制器组件使用布局元素信息的例子,包括ContentSize Fitter和各种各样的Layout Group组件。Layout Group布局各个元素的基本原则如下:

         1)首先分配最小尺寸(Minimum Size);

         2)若有足够可用空间,则分配建议尺寸(Preferred Size);

         3)若仍有额外可用空间,则分配灵活尺寸(Flexible Size)。

         任意含有Rect TransformGameObject都可以作为布局元素。它们默认的MinimumPrefrred以及Flexible尺寸均为0。特定脚本在挂载到GameObject时会改变这些布局属性值。

         图片(Image)和文本(Text)组件是提供布局元素属性的两个例子。它们会调整Preferred 宽度和高度来适应精灵(Sprite)和文本内容(Text Content)。

 

6.1.1 Layout Element Component

         若想覆盖MinimumPreferred以及Flexible的值,只需挂载Layout Element组件到GameObject即可。

        

         LayoutElement组件可以覆盖其中一个或几个的布局属性值。勾选某一行,即可修改对应属性值。

 

6.2 Understanding Layout Controllers

         布局控制器是一类控制组件,用于控制一个或多个控制元素(即挂载RectTransformGameObject)的尺寸和位置。布局控制器可以控制自身节点(OwnLayout Element)以及子节点(Child Layout Elements)。

         布局控制器自身同时也是一个布局元素。

 

6.2.1 Content Size Fitter

         ContentSize Fitter作为布局控制器,用于调节它自身尺寸。若想看看自动布局系统的行为,最简单的方式就是Text(带Text组件的GameObject)挂载Content Size Fitter组件。

        

         若设置Horizontal FitVertical FitPreferred,则Rect Transform会调整宽度或高度来适应Text文本的内容。

 

6.2.2 Aspect Ratio Fitter

         AspectRatio Fitter作为布局控制器,用于调节它自身尺寸。

        

         它可调节高度来适配宽度,或调节宽度来适配高度。它也可调节为内置于父节点区域,或调节为覆盖住父节点区域。Aspect Ratio Fitter忽略Minimum SizePreferred Size

 

6.2.3 Layout Groups

         LayoutGroups作为布局控制器,用于调节子节点尺寸。比如,Horizontal Layout GroupVertical Layout Group一个挨一个排列子节点,而Grid Layout Group则按网格(Grid)排列子节点。

         LayoutGroup并不调整它自身尺寸。但它同时作为布局元素,要么被其他布局控制器调整,要么通过手动调整。

         不管Layout Group被分配了多大尺寸,它都会根据MinimumPreferred以及Flexible来尽可能的调整子节点空间。此外,Layout Groups还支持嵌套使用。

 

6.2.4 Driven Rect Transform Properties

         因为自动布局系统的布局控制器能够自动调整UI元素的尺寸和位置,所以尺寸和位置不应在Inspector视图或Scene视图中手动调整。若手动调整了尺寸或位置,布局控制器依然会自动调整回来。

         RectTransform由属性驱动(DrivenProperties)来达到此效果。比如,设置Horizontal Fit属性为MinimumPreferredContent Size Fitter,会驱动自身GameObject节点的Rect Transform的宽度。Rect Transform顶部的小信息窗口标识了宽度属性为只读,表明一个或多个属性正被ContentSize Fitter驱动。

         这些被驱动的Rect Transform属性还有另外的原因使之不可被手动编辑。调整Game视图的尺寸或分辨率,布局就会改变。此操作会更新布局元素的尺寸和位置,同时会更新被驱动的属性值。然而这并不是我们想看到的,这仅仅是因为Game视图尺寸变更了,就会使得当前Scene标记为未保存。为了防止这一点,变更被驱动属性的值,并不会标记Scene为未保存。

 

6.3 Technical Details

         自动布局系统有一些内置组件,同时还支持自定义方式创建新的控制布局组件。通过继承实现自动布局系统的特定接口(Interface)即可达成此特性。

 

6.3.1 Layout Interfaces

         若一个脚本继承实现了接口ILayoutElement,则它可作为自动布局系统的布局元素。

         若一个脚本继承实现了接口ILayoutGroup,则它可驱动子节点的Rect Transform

         若一个脚本继承实现了接口ILayoutSelfController,则它可驱动它自身节点的Rect Transform

 

6.3.2 Layout Calculations

         自动布局系统按照以下顺序计算与执行布局逻辑:

         1ILayoutElementCalculateLayoutInputHorizontal()计算布局元素的MinimumPreferred以及Flexible宽度。顺序为由下至上,也即子节点先于父节点被计算,这样计算父节点时可兼顾子节点信息。

         2ILayoutControllerSetLayoutHorizontal()计算布局元素的有效宽度。顺序为由上至下,也即父节点先于子节点被计算,这是因为分配子节点宽度需要基于父节点的全部可用宽度。这一步执行之后,布局元素的Rect Transform就有新的宽度。

         3ILayoutElementCalculateLayoutInputVertical()计算布局元素的MinimumPreferred以及Flexible高度。顺序为由下至上,也即子节点先于父节点被计算,这样计算父节点时可兼顾子节点信息。(类似1

         4ILayoutControllerSetLayoutVertical()计算布局元素的有效宽度。顺序为由上至下,也即父节点先于子节点被计算,这是因为分配子节点宽度需要基于父节点的全部可用高度。这一步执行之后,布局元素的Rect Transform就有新的高度。(类似2

         由上述可见,自动布局系统先计算宽度,后计算高度。所以,计算高度取决于宽度,反之计算宽度不需要考虑高度。

 

6.3.3 Triggering Layout Rebuild

         当组件的某个属性改变了,使得它的布局不再有效,那么此时需要重新计算布局。可调用以下代码触发:

         LayoutRebuilder.MarkLayoutForRebuild(transform as RectTransform);

         重建布局并不会立即执行,而是在当前帧即将结束时,在渲染前执行。不立即执行的原因是同一帧可能有多次重建布局,若每次调用都立即执行,这对于性能来说不是好事。

         建议调用重建布局方法的时机:

         1)当设置属性可能改变布局时;

         2)以下回调:

         OnEnableOnDisableOnRectTransformDimensionsChangeOnValidate (编辑器需要,运行时不需要)OnDidApplyAnimationProperties

点击访问官方英文文档 

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引