大家好,

快速了解为什么这个东西存在 - 我觉得RectTransform、锚点和布局组件从来就不太直观。最简单的意图每次都变成一个谜题:

  • 我如何让一个元素占据父元素的50%宽度
  • 我如何保持某个元素的固定宽高比
  • 我如何让一个元素占据剩余空间旁边一个固定元素?
  • 我如何仅仅让几个元素排成一行,间隔

为了解决这些问题,你需要使用一堆单独的组件 - 锚点和转轴、HorizontalLayoutGroupVerticalLayoutGroupGridLayoutGroupLayoutElementContentSizeFitterAspectRatioFitter - 并记住哪些组合产生哪种行为。 我不想在布局时混乱十几个组件,只为了说“一行,间隔均匀”。 我喜欢uGUI,并且我有很多项目在上面,所以离开它不是我的计划 - 我只是想直接表达意图,让布局自动跟随。

如何工作

要将元素放入布局引擎中,你只需要添加一个组件,而每个问题就变成该组件上的一个单独设置:50%宽度是百分比,固定宽高比是宽高比,“占据剩余空间”是填充,大小自适应是紧抱,“一行,间隔”是布局类型,间隔值是间隔

所以,你需要选择每个元素的大小单位像素紧抱填充百分比宽高比)和布局类型网格绝对自定义) - 这就是整个模型。 没有堆叠的布局组件,没有锚点的计算,没有组合的适配器需要记住。 虚拟化的ListView/GridView/ScrollView作为自己的组件,基于同样的底层核心。 因为大小是相对的,所以布局也会在不同分辨率下重新布局 - 这是另外一个好处,并不是我构建它的原因。 它可以与你的现有uGUI一起运行,所以没有迁移和新的UI系统需要学习

在内部

我构建了一个独立的、引擎无关的核心,而不是将其集成到uGUI中 - 我想解决布局问题一次,所以将来转移到UI Toolkit时,不需要重新构建它。 一个薄适配器将结果映射到RectTransform上,而核心的分离意味着我可以在独立测试布局逻辑。

我并没有发明算法 - 布局的形状遵循子表单布局模型和Morphorm的Rust版本:一个两次遍历的树,一个约束求解器。 一个从下往上的遍历计算紧抱/固有大小,从内容开始往上, 然后一个从上往下的遍历将每个父元素的剩余空间传递给其填充/百分比子元素,并设置位置。 每个节点都携带一个轴上的单位,这就是为什么“占据父元素的50%宽度”是一个属性,而不是一个组件堆栈。

因为核心是一个平面数组的可拷贝结构,所以整个遍历都可以通过Burst进行 - 单线程,但可测量的快,并且零GC(以下数字)。

当前状态:uGUI是正在运行的版本。 同样的核心也在IMGUI和UI Toolkit的原型中运行 - 它可以工作,但不是生产就绪的,更多的是一种未来方向,而不是一个承诺。

几个数字

(苹果芯片,编辑器中;只测量布局遍历时间,不包括GameObject的实例化时间。)

无头核心很快且无分配 - 它可以解决一个~1000节点的树在0.12毫秒内(并且~2400节点在0.29毫秒内),近线性的,零GC。 如果Burst关闭,并在管理的fallback上运行相同的求解,速度将降低约6倍,所以编译的核心确实在做工作。

通过uGUI适配器(它也会写出每个RectTransform),以下是强制全局重新布局与同样的层次结构,使用Unity的布局组件进行比较:

相同层次结构,全局重新布局 自适应布局 原生uGUI
嵌套行,~840个节点 5.7毫秒 13.6毫秒
深度嵌套,~1000个节点(9层) 7.4毫秒 22.5毫秒
网格,~840个单元 5.6毫秒 5.6毫秒

所以比嵌套的布局组件快约2倍,并且在深度嵌套时比原生uGUI快约3倍,并且与GridLayoutGroup打平 - Unity的一个瘦身的固定单元组件,它是公平的,因为自适应布局的网格也支持跟踪,跨越和自适应流动。

注意事项:强制全局重新布局在两侧,一个机器上;自适应布局也支持增量重新布局,这些测试中没有使用,数字会根据层次结构而不同。

试试

WebGL示例(去破坏它): [https://autolayoutpro.com/demo](https://autolayoutpro.com/demo) - 它还没有展示所有功能,正在进行中,我会继续扩展。 它是完全基于代码构建的,使用FluentUI API, 并且我会将示例项目放到GitHub上作为一个工作例子。

更多信息/截图: [https://autolayoutpro.com](https://autolayoutpro.com) (在Unity Asset Store上作为“AutoLayout PRO for uGUI”)。

🎁 发布活动 - 5份

要参与,只需留下评论。 我将在周末随机抽取5名获奖者,并在这个帖子中发布结果;获奖者将通过DM收到代码。 截止日期:2021年8月15日,星期日,12:00 PM GMT。

我想讨论一些问题

  • 你是否会继续使用uGUI还是转移到UI Toolkit,并且是什么驱动着这个决定?
  • 你当前的最糟糕的uGUI布局问题是什么 - 锚点,布局组件/适配器的组合,嵌套组件,还是其他什么?
  • 如果你玩了示例,你的第一个印象是什么,什么会被打破?
  • 是否有其他

感谢,祝好运!