三尺非寒 发表于 2024-8-22 06:38:56

【翻译转载】如果你想要构建一套基于ECS的GUI框架

译者序

本文原文地址:So you want to build an ECS-backed GUI framework | Leafwing Studios (leafwing-studios.com)。翻译和发布本文前,已经得到了原作者的许可。
本人翻译这篇文章的主要是由于尽管该文是从 bevy_ui 这一详细的库出发,但其焦点是讨论GUI框架的计划思绪与范式,同时还介绍了许多已有成果,个人觉得如果有读者对基于Rust的GUI建立感兴趣的话,一定会从这篇文章中学到许多有价值的内容。当然,笔者只是利用自己欠佳的英语水平结合翻译软件来对原文进行了翻译,以是如有翻译上的问题,还请读者指出,感激不敬!
别的,这篇文章由原作者于23年11月编写,当时 bevy 正值0.12版本,在翻译这篇文章的时候已经是24年的8月底,bevy的版本已经更新到了0.14,以是文中关于 bevy 、bevy_ui 的一些建立工作(如PR、讨论等)不一定具有时效性。
原文标题为:"So you want to build an ECS-backed GUI framework",从文章上下文理解看来,实际上应该是"So (if) you want to build an ECS-backed GUI framework"
正文

Challenges and opportunities in the future of bevy_ui
关于 bevy_ui 未来的挑衅与机遇
Alice I. Cecile, Rose Peck|2023-11-27
如果你想要通过Rust(以及其生态)构建一个用户界面,那有什么工具能比实体-组件-体系(ECS)框架更合适呢?它不仅提供了一种范例安全的、流行的状态管理方案,而且最重要的是:这套体系的速度将非常快(显然无需进行基准测试)。
当然,Bevy 确实在这么做!实际上,它已经这样做了好几年。那么,为何它没有在竞争中脱颖而出,赢得数百万人的心,并取代 areweguiyet.rs 呢?
译者注:Are we GUI yet?网站陈列了目前已知的全部基于Rust绑定或实现的GUI框架。这里的“取代”主要含义是为什么Bevy的基于ECS的GUI框架为什么做的并不出众,没有成为某种精良的范例,进而让基于Rust的GUI框架结束百花齐放的局面。
虽然基于ECS模式的GUI可能并不是传统方式,但现有技术表明这并非不可能。flecs在这篇文档中将许多焦点头脑进行了实现,同时也像 belly,bevy_lunex,bevy_ui_dsl,cuicui_layout以及kayak_ui这些库进行了这方面的尝试,使得Bevy的ECS(模式)显现出了巨大的潜力。甚至还有一个名为Polyphony的,独立的,ECS先行的,基于Javascript编写的GUI库(关于它的讨论:Polyphony ECS GUI and future · Issue #1 · traffaillac/traffaillac.github.io)。
事实证明,困扰bevy_ui的大多数问题都不是由、由于利用ECS甚至利用Rust的决定引起的,而是一些无聊、乏味和令人沮丧的内容:编写GUI框架是一项涉及大量容易变动的工作。Bugs、模板代码和缺失的功能击碎了用户和开发人员逐步改进优化代码的意愿。
但在我们深入讨论繁杂的细节之前,有一个重要的免责声明。Alice是Bevy的维护者(译者注:同时也是本文的作者),但不是项目负责人,甚至不是UI方面的专家。Rose是Foresight Spatial Labs的一名员工,她一样平常工作是利用Bevy和传统的web框架(React)来构建重GUI的应用程序。本文相干的论点、意见纯粹是我们自己的,不是最终定性的或官方的话!
这篇文章旨在记录如何制作一个GUI框架,为什么我们要利用ECS,以及我们必要修复哪些部分才能使 bevy_ui 变得更精良。(关于这些内容)我们在许多地方(这里,这里,这里,以及这里)都有过许多重复的讨论,但很少有实质性,落地的实践活动(除了ickshonpe,you rock)(译者注:这位icksphonpe给 bevy_ui 的部分提交了大量的优化、修复代码)。说“bevy_ui应该像我最喜欢的ui框架一样工作”很容易,但实际大将其转化为可行的计划、达成共识并其构建出来却要困难得多。
通过编写一份关于需求、愿景和进展的最新、全面、通俗易懂的文档,我们希望Bevy社区可以或许团结起来解决 bevy_ui 今天遇到的问题,彻底排除各种可能性,并为关键的缺失部分提出可靠的计划。
谁知道呢?大概十年后,你正在阅读这篇文章,空想着编写自己的基于ECS驱动的GUI框架。
在我感到非常疲惫、厌倦的过往中,有三类常见的关于 bevy_ui “脱轨”(译者注:原文为"get derailed")的讨论:

[*]Bevy应该利用一套现有的GUI框架。
[*]一个同时实用于游戏和应用程序的GUI框架是不可能的。
[*]您无法在ECS中构建GUI框架。
为什么不直接用egui(或是dioxus,或是tauri,或是iced,或是yew)?

如今已经有非常多的基于Rust的GUI框架,此中一些甚至一直在积极地维护,编写文档以及增加基本功能!
社区已经为此中一些制作了出色的crates,像Foresight这样的公司甚至利用这些第三方GUI框架制作了复杂的生产应用程序。
Bevy想编写我们自己的ui实现,显然是"非我发明"综合症的典型案例(译者注:重复造轮子)。当我们可以利用现有的解决方案来编写即将到来的 Bevy Editor 时,为什么要将稀缺的精力(和决策)用于此?毕竟,我们可以与Dioxus完成一次正式的合作,以此省下许多年的工作量。
然而,以下是我们基于技术以及社会方面考虑的,以为Bevy不应该这样做的原因:

[*]与引擎的其他部分保持同等性是非常有价值的:
[*]为新用户提供了更简朴、更同等的学习上的体验。
[*]这样做使得体系更容易维护。
[*]将全部更改保存在同一个代码堆栈中,从而消除了在存在依赖树的情况下,对于版本发布要更加胆小如鼠处置惩罚的须要。
[*]同等性让UI模块可以或许从引擎其他模块的改进中也受益,反之亦然。Cart信赖许多挑衅并非是UI模块独有的,我们对此表示赞同!

[*]Bevy已经为GUI库必要完成的许多焦点任务提供了一个很好的解决方案。
[*]渲染、状态管理、资产asset、输入、窗口、异步等等。
[*]为什么我们要再次接纳重复的、或许微妙不兼容的方法来完成这些任务?

[*]将数据发送到外部UI框架和从外部UI框架接收数据本身就容易出错,逻辑会变得复杂,难以维护,并且充斥着许多样板代码。
[*]我们不可避免的必要提供集成层来面对不匹配的数据模子。
[*]这并不是UI模块独有的:bevy_rapier在物理方面也遇到了雷同的问题(尽管它仍然是一个精良的库)。

[*]打破目前“屏幕上的盒子(boxes on a screen)”这一UI标准的计划思绪,将会使得近况变得更加困难。
[*]天下空间UI(World-space UI)是游戏的一个关键功能,涉及到:单元叠加(unit overlays)、VR菜单、计算机屏幕等等。
[*]游戏UI往往希望与游戏天下状态精密结合,并具有差别寻常的艺术结果。
[*]利用第三方解决方案编写自定义着色器来覆盖某些节点的行为会变得更加困难。

[*]现有的Rust GUI项目都没有很好地回答解决一个事实:借用检查器非常讨厌图这样数据结构以及讨厌拆分(数据)可变性。
[*]通过添加关系relations,Bevy保证了一种在Rust中处置惩罚图数据关系的独特而强大的方法。
[*]Bevy的体系是一个机动的、无panic的、快速且可靠的解决方案,用于共享对天下状态的可变访问。这背后有许多黑邪术,亲爱的天主,我们不想解释两次了(译者注:可以在这里了解)。

[*]其他项目不由Bevy项目运营。
[*]我们的目标可能会有所差别:例如,egui是专注于简朴、快速构建的UI,为了达到这一要求,它必要在性能和可定制性之间做出衡量取舍。
[*]改动会变得更难协调:我们必要迁移PR,并且无法快速添加编辑器所需的功能。
[*]上游的依赖库可能(再次)被废弃。如果Bevy计划继续存在几十年,所依赖其他库的UI解决方案也会一并存在吗?
[*]我们无法保证某一个关键依赖项的质量。
[*]它给那些较小的以是依赖的第三方库带来了很大的维护压力,由于会让如此大的客户端向它们发出优化、fix的请求。

[*]许多建议提到的第三方GUI库由于它们通常依赖于C、C++或JavaScript等其他语言生态,使Bevy的构建和分发过程变得非常复杂。
[*]不要太苛刻,但许多现有的Rust GUI解决方案,只是不是那么完美。
[*]虽然我们有许多可以或许接受的选择,但它们都有不小的缺点。没有人真正成为赢家。
[*]Are we GUI yet?说“根不深,但种子已经播下”("The roots aren't deep but the seeds are planted.")是有原因的。
[*]在心田深处,我们都知道我们可以做得更好,并且我们应该做得更好。

[*]喜欢第三方GUI解决方案的用户可以并且无论如何都会利用它们。
我们会学习其他GUI框架吗?当然。我们会正式大规模接纳它们吗?绝对不会。
一套GUI框架来统领全部?

在讨论 bevy_ui 时,另一个常见的友善问题是“我们真的能用一个UI框架来满足全部效户的需求吗”?
我看到了一些潜在的分歧:

[*]应用程序UI vs 简朴游戏UI vs 复杂游戏UI
[*]一些热爱CSS以及web应用开发的人 vs 恨它们的人
[*]程序化的程序员友好型GUI vs 资产驱动的艺术家友好型GUI
[*]立刻模式GUI vs 保留模式GUI
我信赖你能想到更多,分歧很容易出现,也很有趣!理论上,我们可以参考Unity(译者注:原文“pull a Unity”,但译者觉得可以理解为参考Unity,意思是“再搞一个雷同的”),并在Bevy中创建多个相互竞争的UI框架。但我们以为这将非常糟糕,由于:

[*]这对用户来说非常狐疑。
[*]它分散了开发人员的留意力。
[*]对于用户来说,很难衡量到底要利用哪种解决方案。
[*]在两个相互竞争的解决方案之间进行迁移会非常痛楚。
[*]在同一个项目中利用多个解决方案从根本上是站不住脚的。
[*]必要两倍的时间(如果你幸运的话)。
幸运的是,“在多个用户群体的差别需求中找到正确的所需的东西”并不是UI独有的问题。我们有很好的工具在架构层面管理这一点:

[*]这个问题其实算是一种假设,由于实际上已经在web开发上得到了解决:

[*]我们不会争辩说web UI是否是有史以来最伟大的UI解决方案(它有许多明显和不明显的缺陷)。
[*]但事实上人们已经乐成构建了几乎任何一种你能想到的利用HTML/CSS/JavaScript来搭建的UI:网页、代码编辑器、游戏(浏览器和独立版)、CAD应用程序、终端等。有一个常见的笑话是“未来一切都是chrome(铬,但实际指Google的Chrome浏览器)”(谢谢Electron)
[*]值得说明的是,web UI技术栈并不是为大多数用例计划的。可以说,它不是为他们中的任何一个单独计划的!

[*]模块化:确保用户可以移除或留下解决方案中某些他们不喜欢(或喜欢)的部分。

[*]组件、体系、插件和Rust库crate的feature特性都非常实用于模块化!
[*]第三方UI库如今存在着,并将继续存在。

[*]可扩展性:确保内部构件可访问且可构建。

[*]公共组件以及资源真的很有用。
[*]想象一下,一个基于 bevy_ui 的可交互扩展库构成的丰富生态体系,全部这些库都建立在我们的焦点渲染、交互和布局规范之上。

[*]抽象计划中的渐进式披露(Progressive Disclosure)。

[*]widget部件是由节点构建的。
[*]节点只是实体。
[*]在整个过程中,没有什么能制止你在较低的条理进行hook(译者注:Hook)。

如果用户可以将雷同的ECS和渲染工具用于从像素艺术平台到单元着色视觉小说(cell-shaded visual novels)再到PBR竞技场射击游戏的一切实现,那么我们就可以创造出一个足够机动、舒服的,适合每个人的UI解决方案。
ECS中的GUI:bevy_ui实际上是如何工作的?

解决了这些常见的反对意见后,我们有望开始讨论如何实际构建我们的UI框架。让我们考虑一下我们的实际产物需求,这样我们就可以看到 bevy_ui 的不足之处。
不幸的是,对我们来说GUI框架是极其复杂的“野兽”。此中某些部分是如此重要,以至于将它们排除会粉碎整个体系:

[*]存储节点树(Storing a tree of nodes)
[*]几乎每个精良的UI范式都有一个或多个嵌套的元素树。
[*]“节点”是这样的元素:UI中最小的不可再分割的原子。
[*]你必要把这些数据存储在某个地方!
[*]在 bevy_ui 中,节点树存储在天下World中:每个节点都是一个具有node组件的实体。
[*]UI实体通过利用父组件和子组件毗连在一起。

[*]布局(Layout)
[*]一旦有了一组节点后,我们希望可以或许形貌它们在屏幕上的位置。
[*]只是简朴地指定绝对巨细和位置并不是很稳健:当添加、删除节点,或屏幕巨细更改时,这样的布局可能会遭到粉碎。
[*]在 bevy_ui 中,通过Style组件指定布局(这名称得怪CSS,抱歉)。
[*]bevy_ui 利用了taffy(Alice帮助维护!):它支持flexbox弹性盒子和css-grid网格的布局策略。
[*]如果你不想受到Web布局算法的束缚,morphorm(在我们看来)是一个更好的选择。

[*]输入(Input)
[*]以键盘按压、鼠标点击、鼠标移动、触摸屏点击、游戏手柄输入等情势收集用户输入。
[*]通常与“拾取(picking)”相匹配:根据位置找出鼠标指针事件关联的元素。
[*]理想情况下,为涵盖悬停、按下、开释和长按按钮等操作计划一套不错的抽象概念。
[*]bevy_ui 依赖于 bevy_input,而 bevy_input 又从 winit 和 gilrs 这些底层库中得到数据。

[*]文本(Text)
[*]将字符串转换为像素以便于我们可以或许将它们绘制到屏幕上。
[*]在所包罗文本的UI节点的边界内分列这些文本。
[*]准确的像素对渲染很重要,但巨细尺寸作为节点布局的输入同样也重要。
[*]bevy_ui 当前正利用 glyph_brush 进行文字字符渲染。
[*]cosmic-text 对非拉丁文字有更好的塑形(shaping)支持。

[*]窗口管理(Window management)
[*]创建一个(或n个)窗口来绘制UI。
[*]bevy 利用 winit,你也应该用它。

[*]渲染(Rendering)
[*]将UI的元素绘制到用户屏幕上。
[*]Bevy利用 bevy_render,而其内部进而利用 wgpu。
[*]如果你正在构建自己的Rust GUI框架,试试vello!

[*]状态管理(State management)
[*]保持对UI状态的持久性跟踪。
[*]添补的文本内容,单选按钮,动画进度,菜单是打开照旧关闭,暗/亮模式等。
[*]在 bevy_ui 中,状态作为组件存储在实体上(或者少量的状态作为全局资源)。这工作得非常好!

[*]数据传递(Data transfer)
[*]将数据从UI传输到其他数据结构进行存储,反之亦然。
[*]在Bevy的上下文中,“其他数据存储”是存储您全部游戏/应用程序状态的ECS World天下。
[*]数据绑定是一种用于自动化此过程的抽象:自动和精细地进行数据的变动传递。
[*]目前,bevy_ui利用体系(system)在world其他部分往返发送数据。

在此基础上,您可能希望 bevy_ui 添加如下的功能:

[*]导航(Navigation,GUI页面上元素导航)
[*]以有原则的离散的方式浏览GUI菜单元素:“tab键”是常见的键绑定。
[*]导航对键盘和游戏手柄都非常有用。
[*]传统应用程序的重要可访问性功能(accessibility,a11y)。
[*]bevy_ui 对这块还没有第一方的解决方案。

[*]样式(Styling)
[*]widget部件和节点具有大量主要是样式性的属性。
[*]我们希望确保我们的应用程序具有同等的外观和体感,并能完成快速更换。
[*]对于应用程序(尤其是移动应用程序)来说,我们期望可以或许达到原生外观和体感。
[*]样式可能接纳以下情势达成实际结果:
[*]级联继承(如CSS)。
[*]选择器(如CSS中的选择器,或您可能利用在 bevy_ui 中提供的查询能力编写选择器)。
[*]全局主题,例如白天明亮模式以及夜间暗黑模式。
[*]widget部件支持某些特定样式。

[*]样式通常必要有可预测的组合规则:当多个样式同时影响一个元素时会发生什么?
[*]bevy_ui 目前没有任何第一方的抽象计划。

[*]可组合、可重用Widget部件的抽象计划(An abstraction for composable, reusable widgets)
[*]即使是简朴的部件范例(单选按钮、文本输入框),代码编写利用起来也相称复杂!
[*]用户应该可以或许一次性编写这些代码,然后在整个项目中重用(reuse)它们,从而进步开发效率和以及保持UI同等性。
[*]部件可以由一个或多个节点/元素构成。
[*]每个部件的节点数量可以动态变化:想想不断增长的待服务项列表。
[*]部件必要可以或许接受参数来更改其内容或行为。例如,创建一个具有可自定义文本的可重用按钮。
[*]bevy_ui 目前利用Bundle范例,但由于无法处置惩罚多个节点,因此算是较为失败。

[*]动作行为抽象(Action abstractions)
[*]撤销-重做。
[*]可重新绑定热键。
[*]命令选项板。
[*]bevy_ui 对此没有第一方解决方案,甚至第三方解决方案也不成熟(抱歉!)。

[*]可访问性(Accessibility)
[*]为UI创建并暴露机器程序友好的API:读取状态、控制渲染/表现、发送输入并检测这些输入更改时会发生什么。
[*]通常可以或许对键盘导航进行hook。
[*]提供API供屏幕阅读器等工具利用,这些工具提供了一个可供选择的用户界面,以满足残疾用户的需求。
[*]bevy_a11y hook到accesskit,你的GUI框架也应该如此。
[*]关于可访问性,存在许多事项必要讨论,但不幸的是,我们在这里没有详细事项统计。

[*]本地化(Localization)
[*]存在不止一种用户语言:你必要一种方法来变动UI元素(尤其是文本),以满足喜欢差别语言的用户的需求。
[*]有些语言是从右向左而不是从左向右阅读的,如果不考虑这一点,某些UI计划往往会倒退(backwards)。
[*]图标和表情符号在差别的地方也有差别的文化含义。
[*]说真的,用fluent就行了。

[*]资产管理(Asset management)
[*]UI经常利用预先渲染的图像或图标作为视觉结果,尤其是在游戏中。
[*]你可能想要自定义的UI的结果和图标等,或者以自己的方式表现图像和视频。
[*]bevy_ui 利用bevy_asset来完成它

[*]动画(Animation)
[*]小动画,特别是一些UI元素发生变化时的小动画,可以显著进步UI的风雅度和丰富性。
[*]折叠/展开上下文菜单,滑动抽屉,旋转加载图标,淡入/淡出等动画结果。
[*]bevy_ui 理论上与bevy_animation集成在一起,但集成还没有完善(译者注:翻译这篇文章的时候,已经集成发布了)。

[*]调试工具(Debug tools)
[*]渲染后快速检测,修改UI节点树。
[*]调试工具对于定位bug和调试过程中摆弄(twiddling)样式非常有用。
[*]bevy_ui 对此没有解决方案,但 bevy_inspector_egui 做得很好。

[*]UI序列化(内存中对象到文件)和反序列化(文件到内存中对象)(UI serialization (in-memory object to file) and deserialization (file to in-memory object))
[*]如果我们可以根据存储在文件中的定义并构建UI,那么我们可以:
[*]使得外部工具(如游戏编辑器)更容易构建UI。
[*]让客户端用户更容易自定义UI(想想Greasemonkey和游戏模组)。
[*]构建调试工具会更容易实现和利用。
[*]减少编译时间:只需热更新UI资产。
[*]答应完全控制用于定义对象的格式和语法(译者注:好比创造DSL)。
[*]提供了更好的模块化工具的潜力,可以在不修改源代码的情况下创建更高级别的抽象和自动化迁移。

[*]在游戏中,这被称为“数据驱动”方式。
[*]bevy_ui 当前利用场景scenes(来自bevy_scene)来实现UI序列化和反序列化。

[*]异步任务(Asynchronous tasks)
[*]有的任务工作是由UI触发的,但是必要很长时间才能完成。
[*]当发生上述情况时,你肯定不希望你的程序处于一直UI冻结的状态。
[*]在 bevy_ui 中,利用 bevy_tasks 来实现。

为什么 bevy_ui 很糟糕?

通过hook到功能齐全(但尚未完成)的游戏引擎Bevy,bevy_ui 实际上在大多数这些领域都有初步的解决方案!
那么,为什么绝大多数人以为它比Bevy更像Bavy呢(more Bavy than Bevy)?在听取和整理了用户利用 bevy_ui 的体验后,以下是 bevy 0.12版本中,按照对用户体验的主观印象进行分列的,关于 bevy_ui 的关键问题:

[*]天生具有大量自定义属性的实体必要大量的样板:

[*]无限嵌套的以及到处可见的..Default::default()。
[*]当处置惩罚树中分列的多个实体时,情况会变得更糟。如前所述,你不能在此场景利用bundle。
[*]数据驱动的工作流并没有被广泛利用,由于Bevy的场景冗长且文档不足。

[*]Bevy必要为UI部件拥有一套真正的抽象:

[*]并非全部widget部件都可以有意义地表示为单个实体。
[*]Bevy提供了很少的预构建好的widget部件:我们只有按钮和图像。
[*]由于我们缺乏标准化的抽象,即使添加最简朴、最有用的widget部件也会引起争议并陷入逆境。(必要明确的是,这不是审稿人或作者的错)

[*]在schedule中利用体系不太适合数据绑定:

[*]UI的行为几乎总是一次性(one-off)的或非常离散稀疏的(very sparse)。(译者注:而ECS体系下的体系总是每一轮都在进行实行)
[*]从UI侧启动的任务要么通常很小,要么通常将其放入异步任务池中。
[*]我们真的希望可以或许引用一个单一的特定实体及其父实体和子实体。
[*]解决这个问题必要创建几十个标记组件(Marker Component):几乎每个按钮、文本框、图像、容器等都有一个。

[*]99%的时间,这些处置惩罚UI事件的体系不会工作,比较浪费时间,由于schedule模块必须不断轮询以查看是否必要做任何事情。

[*]在 bevy_ecs 中管理和遍历条理结构(向上或向下)真的很糟糕:

[*]Relations关系管理短时间还不会实现。

[*]Bevy的UI输入处置惩罚非常的原始:

[*]用于处置惩罚指针输入的Interaction交互组件利用起来非常有限了。
[*]对移动端多点触控支持也非常有限。
[*]键盘和游戏手柄导航目前是缺乏支持的(译者注:翻译此文章的时候已经支持了)。
[*]对于可配置的按键绑定,没有第一方动作行为抽象支持。
[*]Bevy的“picking选取”支持非常简朴,且不容易扩展到非矩形元素或天下空间中的元素。(bevy_mod_picking加油!)

[*]Flexbox弹性盒子布局(以及小范围的CSS Grid网格)很难学习,有令人沮丧的边沿案例情况,还有糟糕的API。你能解释一下flex-basis是什么吗?
[*]由于不久前的修复错误,bevy_ui 中的字体渲染有时非常丢脸。
[*]Bevy缺失了样式抽象:

[*]如今我们已经完成了实现:只需修改组件即可!

[*]为 bevy_ui 添加非常规的视觉结果太难了:

[*]我们缺少圆角:这对美观的UI至关重要。(它们目前在UI方面非常流行。我们可以等几年让它们过期,但无论如何,它们都会在几年后回来。)
[*]我们也没有阴影,但没人在乎。
[*]我们缺少九宫格布局支持(nine-patch support):这对美观但也机动的基于资产定义的UI至关重要。
[*]在Bevy 0.12的UI材质(功能发布)之前,没有另外一条路可以让你在 bevy_ui 中添加自己的渲染抽象。

[*]用纯代码或通过手工编写场景文件来构建UI可能会很痛楚且容易出错:如果有一款可视化编辑器将会很棒。
[*]天下空间的UI的支持程度很差,并且利用了一套完全差别的工具。

[*]这对于游戏(生命条、单元帧)至关重要,对于GIS或CAD应用程序中的标记和标签等也非常有用。

[*]bevy_ui没有对动画的一级支持。
[*]bevy_ui节点都有Transform和GlobalTransform 组件,但不答应开发者利用它们。
[*]在Bevy中处置惩罚异步任务的人体工程学计划是令人沮丧的:必要对实行的任务进行手写代码跟踪和轮询太多。
在这些问题中,只有1(实体天生样板代码过多)、2(widget部件的抽象不足)、3(体系不适合UI事件回调)以及4(UI节点条理结构处置惩罚令人痛楚)是由于我们选择利用ECS架构而引起的。别的的都是标准的GUI问题:无论你利用什么范式,都必要解决这些问题。关键的是,每一个与ECS相干的问题都是Bevy应该为其他用例修复的:

[*]天生自定义实体(尤其是实体组合)对于常规的游戏代码来说很糟糕,场景scene也不是最佳实践。例如,我们天生一个玩家及其全部武器。
[*]Bevy缺少一种涵盖多实体条理结构的代码定义级别的抽象:bundle也支持的不够好。
[*]一次性体系实用于各种定制的复杂逻辑,我们必要创造一套开发模式来有用地利用它们。
[*]Bevy的对于处置惩罚层级继承等部分的实现从根本上来说是缓慢、脆弱和痛楚的。Relations关系计划必要首要一级支持。
ECS和GUI之间没有根本上的模式不匹配或架构不兼容。bevy_ui 并不是一个有根本缺陷的概念计划,只是它的ECS部分的基础还不够好。
bevy_ui的前进之路

让 bevy_ui 真正强大还有很长的路要走,但我们可以一步一步脚踏实地。尽管我们面临着一些悬而未决的问题,以及即将对焦点组件进行重写的事项,但这并不意味着 bevy_ui 中的全部内容都应该被毁灭移除。GUI框架涉及大量复杂的,独立的子组件:一个领域模块的改进不会因其他领域模块的重写而无效!
我们可以把要做的工作分为三类:毫无争议的部分,有争议的部分以及待研究的部分。
没有争议刀切斧砍的部分只必要解决掉它们即可。这些任务可能很容易,也可能比较困难,但对于如何或是否应该这样做,不应该有太多的分歧。就目前,这类事项包罗:

[*]检视以及归并UI圆角支持。
[*]检视以及归并九宫格布局支持。
[*]检视以及归并实现动画插值与混淆能力的Animatable特性。
[*]检视以及归并winit更新,它包罗了对各种BUG的修复以及功能优化。
[*]末了,检视并归并将ab_glyph迁移为cosmic-text的PR,该部分解锁了体系字体和复杂字体的利用。
[*]添加对天下空间UI的支持,开始着手查看和归并基于摄像机驱动的UI的PR。
[*]添加对UI不透明度变化的支持。
[*]添加更多关于 bevy_scene 的文档、示例和测试,使其更容易扩展和学习。
[*]为Bevy中的多点触控输入添加更好的示例和功能。
[*]改进Bevy中关于处置惩罚异步任务的人体工程学计划。
[*]在taffy中添加Morphorm和/或cuicui_layout布局策略,并在Bevy中暴露出来。
[*]添加数十个widget部件(但目前由于围绕精良的widget部件抽象还未达成共识)。
有争议的事项是那些我们对其具备清晰的理解和广泛的共识,但完成它们会产生重大的架构影响的事项,好比:

[*]创建一套样式抽象计划,使其通过修改组件值来完成工作:
[*]Alice写了一个非常古老的RFC来说明这是如何工作的,bevy_kot提供了一种样式级联的方式,viridia的quill的实验也有一个很好的提案。

[*]上游的bevy_fluent,将会在bevy项目标掩护之下进行长期的维护。
[*]添加对键盘以及游戏手柄的导航支持,并将其加入到 bevy_a11y 中。
[*]为如何处置惩罚指针事件和状态添加适当的抽象。
[*]优化并实现Cart的bsn提案,以进步场景的可用性:
[*]这是受到现有作品(如cuicui、belly和polako)的开导并与之密切相干。

[*]添加雷同bundle的抽象,但实用于多级条理组合:
[*]添加一个bsn!宏,以便更容易实例化Bevy实体,特别是利用较少样板代码的实体条理结构。
[*]添加一种通过派生宏从结构体天生这些多条理实体的方法。
[*]现有技术包罗bevy_proto和moonshine-spawn。

[*]添加插值颜色的方法以提拔UI动画结果。
[*]创建一个UI特定的变换范例,以实现更快的布局和更清晰,范例更安全的API。
[*]为 taffy 中添加在单个节点树中的混淆布局策略的支持。
[*]在bevy_easings和bevy_tweening这两个库完成后,添加对动画缓动(easing)/tween的支持。
[*]利用上游的leafwing-input-manager库,用于提供对按键绑定的抽象。
[*]利用上游的bevy_mod_picking库,解锁高性能、机动的元素选择。
[*]实现Relations,并将其应用到 bevy_ui 中。
研究任务必要具备相干重要的计划专业知识,必要仔细考虑截然差别的提案,可能没有明确的要求必要干嘛:

[*]定义并实现一个标准的UI widget部件抽象:
[*]可组合的:widget部件可以与其他部件组合以创建新的部件范例。
[*]机动的:我们应该可以或许利用这种抽象来支持从按钮到列表再到选项卡视图的全部内容。
[*]可配置的:用户可以更改widget部件某些重要属性来达成结果,而无需重复创建自己的范例。
[*]或许可以映射到一个或多个Bevy实体,利用普通体系就可以对widget部件进举措态更新。
[*]可在Bevy场景之间进行序列化。

[*]弄清楚我们希望如何处置惩罚UI行为(和数据绑定),以避免由于利用ECS中的体系system而卷入其他的问题:
[*]这是Alice创建一次性体系的最初动机。
[*]事件冒泡和各种各样(quill、bevy_kot)的相应式UI尝试(futures-signals、bevy_rx、u4)似乎是有趣的潜在工具库。
[*]虽然并不总是直接实用,但Raph Levien在Xilem上的帖子很有趣,值得一读。
[*]数据模子是一项关键的挑衅:很容易陷入全部权问题。

[*]弄清楚如何将数据绑定逻辑集成到Bevy场景中:
[*]Callbackas Asset这个PR看起来很有希望。
[*]Vultix提出了一种用.bsn文件定义数据绑定的语法和策略。

[*]构建Bevy编辑器,并实现利用编辑器构建GUI场景的能力:
[*]这里存在一种“循环依赖”:bevy_ui 越好,编辑器构建起来就越容易(,编辑器构建越容易,利用 bevy_ui 构建GUI就越好用)

显然,还有许多工作要做!但关键的是,并没有什么是完全不可能的。如果我们(Bevy开发者社区)可以或许团结起来,一次一个稳步地解决这些问题,我们(Alice和Rose)真的以为 bevy_ui 总有一天会达到我们对引擎其他部分所期望的质量、机动性和人体工程学的标准。
感谢您的阅读:希望它具有教育意义、发人深省和/或有趣。如果你想在未来阅读更多这样的内容,可以考虑注册我们的电子邮件列表或订阅我们的RSS。
译者写在末了

尽管有翻译工具的帮助,但是为了读懂原作者的意思,照旧必要结合Bevy这个库以及ECS概念。翻译这篇文章也花了一定的时间,感谢读者的耐心阅读。
本文也会同步发布到本人的博客上:zhen.one(真一),欢迎小同伴访问。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 【翻译转载】如果你想要构建一套基于ECS的GUI框架