#bevy-ui #layout #bevy #ui

cuicui_layout

为 bevy 设计的、易于人类理解的布局算法

16 个版本 (破坏性更新)

0.12.0 2023年11月10日
0.10.2 2023年10月25日
0.8.0 2023年7月19日

#2108 in 游戏开发

每月 37 次下载
用于 3 个 框架

MIT/Apache 协议

175KB
3K SLoC

cuicui_layout

The Book Documentation

cuicui_layout 是 bevy 中为 bevy 实现的一个非常原始的布局算法。

它类似于 CSS,但没有那么复杂。其哲学是

你可以始终预测它的外观

cuicui_layout 完全独立于其他 cuicui 框架,你可以禁用所有默认功能,并拥有一个仅添加布局组件和系统的裸骨插件。

然而,cuicui_layout 也与 cuicui_dslcuicui_chirp 集成。

请参阅它们各自的文档页面,了解为什么你想使用它们。

何时使用 cuicui_layout

cuicui_layout 总是比 Flexbox(默认的 bevy UI 布局算法)更好的选择。但我并不声称它比其他类似的非 Flexbox 布局算法更好。

以下是一些你为什么可能更愿意选择 cuicui_layout 而不是其他布局算法的原因

  • 友好的算法,需要记住的东西更少,并提供了良好的默认设置。
  • 利用 bevy ECS 的全部优势。
  • 只控制 LayoutRect,而不是 Transform,你需要添加一个系统,根据 LayoutRect 设置 Transform
  • 完全灵活和可扩展,可以与 bevy_uibevy_sprite、你的东西一起使用。
  • 当事情不一致或出错时,提供有用的和详细的错误消息。与 FlexBox 相比,FlexBox 会说“这没问题 🔥🐶🔥”,然后让你猜测为什么事情没有如预期那样发生。
  • 这是一个单遍算法,因此比 flexbox 更高效。
  • 丰富的调试覆盖层。

如何使用 cuicui_layout

Cargo 特性

  • debug:启用调试覆盖层
  • reflect(默认):启用 bevy_reflect 对布局组件的实现。
  • chirp(默认):启用chirp ParseDsl实现,用于LayoutDsl
  • dsl(默认):定义并导出DslBundle实现,用于dsl!

布局

cuicui_layout公开了以下Component来控制布局

  • Node:布局节点,可以是包含其他节点作为bevy Children的容器或叶节点。
  • Root:节点层次结构的根。您可以有多个根,所有计算都从根开始。
  • ScreenRoot:如果您将此组件添加到LayoutRootCamera组件的Root实体,它将保持与相机的相同大小。

请参阅RuleContainer文档以获取详细说明。

简而言之:一个Node在x和y轴上有独立的Rule。当节点是Container时,它还具有额外的属性来管理子节点如何在容器内分布。

这些额外属性包括

  • Flow:子节点分布的方向
  • Alignment:节点在交叉轴上的对齐位置
  • Distribution:如何分布此容器的子节点
  • margin:主轴和交叉轴上的边距

默认情况下,项目在容器的中心对齐,在容器内均匀分布。

Rule告诉Node的大小,它可以依赖于其子节点的大小、其父节点的大小或是一个固定值。

没有更多了,这基本上就是所有的cuicui_layout。如果这还不够清晰,请阅读RuleContainer文档。

内容大小

可以根据同一实体上的组件来调整叶节点的大小。

使用 content_sized 特性来完成这项操作。

调试

cuicui_layout 集成了调试器。通过启用 cuicui_layout/debug cargo 功能来启用它。

调试器是一个覆盖层,显示 Node 的范围和它们规则的方向。

为什么不使用 Flexbox

你正在编写文本,以便在屏幕上获得 2D 可视结果。文本到屏幕的转换应该是微不足道的,很容易在脑海中完成。否则,你需要视觉反馈来得到你想要的结果。Bevy 即使有热重载或 bevy-inspector-egui,视觉反馈也将始终非常缓慢。

Flexbox 有太多参数,并且依赖于 UI 元素的隐式属性,无法在脑海中模拟它。

与 Flexbox 相比,cuicui 的布局容易在脑海中想象。事实上,我将在两个简短的要点中强行将 cuicui 的布局算法推入你的脑海中。

  • 一个节点可以是一个 Node::Container,并沿着 Direction 分配其子元素,要么通过均匀分配它们 (Distribution::FillMain),要么将它们直接一个接一个地放置 (Distribution::Start)。
  • 容器的大小可以表示为静态值,它包含大小的分数,或它包含大小的倍数。
  • 容器的内容可以 Alignment 到其父级的开始、结束或中心(默认为中心对齐)。

就这样。有一些边缘情况,但 cuicui 会在你遇到它们时友好地告诉你,并告诉你如何正确处理。

Flexbox 常见问题解答

:哪里是 padding
:在 cuicui_layout 中,padding 等同于 margin。在概念上,marginborder 没有意义。

:为什么不叫 padding 呢?
:看看“margin”和“padding”在词典中的定义。

:如何居中对齐节点?
:节点默认居中对齐,请确保父级容器的尺寸符合预期。

flex_direction 的等效项是什么?
:使用 rowcolumn

column-reverserow-reverse 的等效项是什么?
:没有。使用 Alignment::End 并交换你的元素!请注意,flexbox 中的 *-reverse 流对于国际化非常有用。然而,当制作游戏时,仅仅交换元素是不够的!艺术控制至关重要,国际化需要在 UI 的上下文中作为一个整体来考虑。

flex_wrap 的等效项是什么?
:没有,你真的需要它吗?

align_itemalign_selfalign_contentjustify_content 的等效项是什么?
:在与 CSS 合作了 5 年之后,我仍然不知道哪一个做什么,以及它们是否真的做了任何事情,所以我不敢冒险回答。

问题flex_growflex_shrinkflex_basisgap的等效功能是什么?
答案: 你知道它们的功能吗?

问题: 为什么子容器不能溢出其父容器?
答案: 这可能出乎你的意料,所以我们将其报告为错误。

问题: 我该如何创建一个网格?
答案: 目前cuicui_layout无法管理节点的网格。这可能在将来添加。

依赖项

~20–56MB
~1M SLoC