恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

Bevy 抽取系统泛化迁移指南:从 bevy_extract 到 AppLabel 的完整改造

  • 首页
  • 资讯中心
  • /
  • Bevy 抽取系统泛化迁移指南:从 bevy_extract 到 AppLabel 的完整改造

相关资讯

Cypress 发布产物构建指南:npm 包与 Electron 二进制的构建、打包与发布流程 2026/9/6 22:33:28
Specify CLI 认证机制详解:auth.json 配置、GitHub / Azure DevOps 鉴权与凭证安全 2026/9/6 22:33:28
WeKnora 版本升级:半小时完成且可回滚 2026/9/6 22:33:28

最新资讯

CSDN技术博客运营全攻略:从Markdown排版到SEO优化实战
Spring Boot + 微信小程序校园跑腿系统实战:从订单状态机到部署上线
扶梯可编程电子安全系统MCTC-PES-E1深度解析:架构、功能与调试
Hindsight 性能调优指南:从延迟排查到配置优化,改善内存占用与查询速度
IOPaint:开源AI修图工具,抹掉照片里不想要的人、水印和文字
Terraform 内部 promising 包:基于二部图的无死锁 Promise 与 Task 并发模型

今日推荐

超人会飞不算本事:系统稳定依赖清晰规则与边界设计
超人VS蜘蛛侠:拆解超级IP的影响力与传播方法论
基于CNN的调制信号识别:MATLAB实现时频图分类实战

本周热门

超人会飞不算本事:系统稳定依赖清晰规则与边界设计
超人VS蜘蛛侠:拆解超级IP的影响力与传播方法论
基于CNN的调制信号识别:MATLAB实现时频图分类实战

本月精选

自研推理加速器Redwood:两周内实现PyTorch模型高效部署的实战教程
V4L2摄像头采集实战:从camera_client.rar到出图全流程解析
从“谁发明了钢琴键”到知识问答智能体:RAG与记忆工程实践

Bevy 抽取系统泛化迁移指南:从 bevy_extract 到 AppLabel 的完整改造

发布时间:2026/9/6 22:38:28
Bevy 抽取系统泛化迁移指南:从 bevy_extract 到 AppLabel 的完整改造 Bevy 抽取系统泛化迁移指南从 bevy_extract 到 AppLabel 的完整改造【免费下载链接】bevyA refreshingly simple>项目地址: https://gitcode.com/GitHub_Trending/be/bevy本篇基于 Bevy 官方迁移文档 extract-extract 展开讲解抽取Extraction系统从仅限 Main World → Render World升级为面向任意子应用Sub App泛化机制后的迁移方法。读完后你能掌握如何在SyncComponent/ExtractComponent/ExtractResource上指定AppLabel、如何用#[extract_app]宏把组件抽取到多个子应用以及新 crate bevy_extract 中各 API 的迁移对照。一、背景抽取机制为什么要泛化在旧版本中抽取是Main World 到 Render World 专属的固定管线渲染管线从主世界同步实体、提取组件数据到自己的子世界sub world。改造后这套机制被抽象为通用的子应用间数据通道任何带有AppLabel的子应用RenderApp、AudioApp或自定义 label都可以作为抽取目标。从 crates/bevy_extract/src/lib.rs 的模块文档可以看到新的设计目标通过为指定AppLabel添加ExtractPlugin完成基础接入派生ExtractComponent或ExtractResource时必须用extract_app属性指明目标子应用派生ExtractComponent会自动追加SyncComponent实现先把主世界的实体同步到子世界再把组件数据从主实体复制到子实体子应用可以在ExtractSchedule中通过Extract参数访问主世界。对应的 crate 结构为 crates/bevy_extract/srcextract_component.rs组件抽取、extract_resource.rs资源抽取、extract_instances.rs高性能实例化抽取、extract_param.rsExtract系统参数、extract_plugin.rs插件与调度、sync_component.rs组件联动清理、sync_world.rs实体同步。二、核心迁移点所有抽取 trait 必须携带 AppLabel迁移文档列出的两条硬性规则使用TemporaryRenderEntity::default()取代TemporaryRenderEntity构造使用SyncComponent、ExtractComponent、ExtractResource等抽取相关 trait 时必须为它们指定目标世界的AppLabel。2.1 前后写法对照Beforeimpl SyncComponent for TemporalAntiAliasing { ... } #[derive(Component, ExtractComponent)] pub struct Foo { ... }Afterimpl SyncComponentRenderApp for TemporalAntiAliasing { ... } #[derive(Component, ExtractComponent)] #[extract_app(RenderApp)] pub struct Foo { ... }2.2 trait 签名层面的具体变化ExtractComponent的新定义见 crates/bevy_extract/src/extract_component.rspub trait ExtractComponentL: AppLabel, F (): SyncComponentL, F { /// ECS [ReadOnlyQueryData] to fetch the components to extract. type QueryData: ReadOnlyQueryData; /// Filters the entities with additional constraints. type QueryFilter: QueryFilter; /// 抽取输出可插入子世界实体的 Bundle。 type Out: BundleEffect: NoBundleEffect; /// 返回 None 时会从子世界实体上移除 SyncComponent::Target。 fn extract_component(item: QueryItem_, _, Self::QueryData) - OptionSelf::Out; }关键语义L是目标子应用的AppLabel如RenderAppF是绕过孤儿规则orphan rules的标记类型默认为()为外部类型实现该 trait 时可传入一个本地类型例如调用方插件的类型Out是插入子世界的Bundle如果主世界组件被移除SyncComponent::Target中声明的组件才会被自动清理见下一节extract_component返回Option返回None即触发对子世界实体的Target移除——这一点在内置抽取系统extract_components中有直接体现extract_component.rs 中else { commands.entity(entity).remove::C::Target(); }。SyncComponent定义在 crates/bevy_extract/src/sync_component.rspub trait SyncComponentL: AppLabel, F (): Component { /// 描述主世界组件被移除时子世界实体上应移除哪些组件。 type Target: BundleEffect: NoBundleEffect; }SyncComponentPlugin会做两件事见 sync_component.rs把SyncToSubWorldL注册为C的必需组件required component使SyncWorldPlugin能感知该实体需要同步注册一个OnRemoveC观察者当主世界组件被移除时向子世界推送EntityRecord::ComponentRemoved记录在同步阶段移除TargetBundle 中声明的组件。ExtractResource同样携带L定义见 crates/bevy_extract/src/extract_resource.rspub trait ExtractResourceL: AppLabel, F (): Resource { type Source: Resource; /// 定义资源如何从主世界转移到子世界。 fn extract_resource(source: Self::Source) - Self; }其提取系统extract_resource具有变更检测优化仅当Source资源is_changed()时才重新计算并写入子世界目标资源见 extract_resource.rs。三、derive 宏#[extract_app]指定一个或多个目标子应用3.1 单目标与多目标抽取单目标写法即迁移文档中的#[extract_app(RenderApp)]。泛化带来的新能力是同一个组件可以同时抽取到多个子应用只需把多个AppLabel作为extract_app的参数列表#[derive(Component, Clone, Debug, ExtractComponent)] #[extract_app(RenderApp, AudioApp)] struct SomeComponent;宏的实现位于 crates/bevy_extract/macros/src/extract_component.rs缺少#[extract_app]属性时会直接编译报错ExtractComponent requires #[extract_app(MyAppLabelA, MyAppLabelB)] to specify the target sub-app(s)L23-L30空参数列表#[extract_app()]同样报错要求至少一个AppLabelL32-L44宏对extract_app中的每个label 分别生成一组impl SyncComponentLimpl ExtractComponentLL84-L101默认QueryData static Self、Out Self、extract_component返回Some(item.clone())。此外宏还支持两个可选属性便于自定义行为而无需手写 trait 实现#[extract_component_filter(FilterType)]指定QueryFilter缺省为()#[extract_component_sync_target(BundleType)]指定SyncComponent::Target缺省为Self。见 extract_component.rs 宏。3.2 双目标抽取有测试背书多目标抽取行为在 crates/bevy_extract/src/extract_plugin.rs 的单元测试dual_extraction_worksL392-L545中得到验证组件RenderComponentDual通过#[extract_app(ExtractAppA, ExtractAppB)]同时派生到两个子应用测试断言两个子世界都包含该组件且主世界移除后两个子世界各自按自身Target独立清理。单目标场景则由extraction_works测试L217-L307覆盖验证了主世界移除组件 → 子世界Target中声明的组件随之移除的联动行为。四、实体同步层的类型变化与TemporaryRenderEntity::default()4.1 同步类型现在带 AppLabel 参数crates/bevy_extract/src/sync_world.rs 中同步相关组件全部参数化SyncToSubWorldLL121-L123标记实体需要同步到L对应的子世界由ExtractComponentPlugin/SyncComponentPlugin自动注册为必需组件通常无需手动插入SubEntityLL128-L130挂主世界实体上记录其对应的子世界EntityMainEntityL157-L159挂子世界实体上记录对应的主世界EntityTemporaryEntityLL194-L197标记实体本帧结束时需要被 despawn。SyncWorldPluginL通过主世界中的观察者把新增/移除记录累积到PendingSyncEntityL资源再由entity_sync_system在每帧抽取前统一执行在子世界 spawn 带MainEntity的新实体、在主世界回填SubEntity或按记录执行 despawn 与组件清理sync_world.rs。其文档注释还给出了主世界/子世界实体的对应关系示意与每帧先 sync 后 extract的时序图L44-L69。4.2 为什么TemporaryRenderEntity必须改用::default()TemporaryRenderEntity现在不再是单元结构体而是 crates/bevy_render/src/lib.rs 中的类型别名L84-L90pub type SyncToRenderWorld bevy_extract::sync_world::SyncToSubWorldcrate::RenderApp; pub type RenderEntity bevy_extract::sync_world::SubEntitycrate::RenderApp; pub type TemporaryRenderEntity bevy_extract::sync_world::TemporaryEntitycrate::RenderApp;由于TemporaryEntityL内部持有PhantomDataL旧的TemporaryRenderEntity字面量构造不再合法需要迁移文档要求的TemporaryRenderEntity::default()TemporaryEntity在L: Default时派生了Default。同样的别名机制意味着你过去在bevy_render里写的SyncToRenderWorld、RenderEntity等类型名保持不变但底层已经参数化到RenderApp。五、ExtractPlugin与抽取流程extract()迁移迁移文档最后一项变更bevy_render::extract_plugin::extract()移到了bevy_extract::extract_plugin::extract()。extract()函数extract_plugin.rs的工作原理值得理解因为它解释了主世界为何只读可查pub fn extract(main_world: mut World, sub_world: mut World) { // 把主世界临时作为资源插入子世界 let scratch_world main_world.remove_resource::ScratchMainWorld().unwrap(); let inserted_world core::mem::replace(main_world, scratch_world.0); sub_world.insert_resource(MainWorld(inserted_world)); sub_world.run_schedule(ExtractSchedule); // 恢复主世界 let inserted_world sub_world.remove_resource::MainWorld().unwrap(); ... }即把整个主世界作为一个World资源MainWorld挂进子世界运行ExtractSchedule结束后再换回来。ScratchMainWorld是预分配的scratch世界避免每帧重新分配L129-L132。配套要点ExtractSchedule文档明确提示该步骤应尽量短以提升流水线pipelining潜力L100-L108ExtractPlugin在构建子应用时把 ExtractSchedule 的自动 deferred 命令应用关闭auto_insert_apply_deferred: false改为在子应用的普通 schedule 中通过apply_extract_commands执行使命令应用可与主应用并行L59-L80在ExtractSchedule中读取主世界数据的系统参数是ExtractPcrates/bevy_extract/src/extract_param.rs它要求内部参数是ReadOnlySystemParam主世界不可被抽取阶段修改文档示例演示了ExtractQuerySubEntityExtractApp, WithCloud的用法L33-L48。5.1ExtractComponentPlugin的注册与仅可见实体变体组件抽取通过ExtractComponentPluginC, L, F注册extract_component.rs。其build逻辑先自动加入SyncComponentPlugin保证Target清理语义再向子应用ExtractSchedule注册抽取系统。性能相关的一点提供ExtractComponentPlugin::extract_visible()构造器L72-L79对应系统extract_visible_components会额外查询ViewVisibility只对当前对可见的实体做抽取L118-L136适合渲染可见性类组件的抽取场景。六、迁移清单Checklist结合迁移文档与 crates/bevy_render/src/lib.rs 的再导出逐项检查你的代码库import 路径bevy_render::extract_plugin::extract→bevy_extract::extract_plugin::extract函数本身已搬家见 crates/bevy_extract/src/extract_plugin.rstrait 实现为SyncComponent、ExtractComponent、ExtractResource及其插件类型ExtractComponentPlugin/ExtractResourcePlugin/SyncComponentPlugin补充AppLabel泛型参数如impl SyncComponentRenderApp for TemporalAntiAliasingderive 宏所有#[derive(ExtractComponent)]/#[derive(ExtractResource)]必须追加#[extract_app(...)]缺少时宏会给出明确的编译错误信息需要多目标时列出多个 label临时实体TemporaryRenderEntity构造改为TemporaryRenderEntity::default()bevy_render再导出兜底大多数抽取类型仍由bevy_render再导出lib.rs 中可见ExtractComponent、ExtractPlugin、ExtractResource、SyncComponent、MainEntity、MainEntityHashMap、MainEntityHashSet及SyncToRenderWorld/RenderEntity/TemporaryRenderEntity别名仅依赖渲染管线的代码可保持旧 import但涉及extract()函数或直接对接非渲染子应用如AudioApp的代码必须改用bevy_extract外部类型实现若你的 trait 实现涉及第三方类型利用F标记类型参数绕过孤儿规则文档建议在调用ExtractComponentPlugin时传入本地类型如插件自身类型。边界与限制本文档描述的是当前仓库 HEAD 的抽取 API 形态适用于正在向此版本迁移的下游项目extract_component返回None只移除TargetBundle不影响子世界实体本身——实体生命周期由SyncWorldPlugin依据SyncToSubWorldL的存在与否决定ExtractPlugin注册时若找不到目标子应用app.get_sub_app_mut(L::default())为None组件抽取系统不会挂载注册顺序上应确保ExtractPlugin::L先于对应组件插件添加Extract参数仅读主世界且只在ExtractSchedule内可用不要在子应用的其他 schedule 中使用。参考文件迁移原文档_release-content/migration-guides/extract-extract.mdcrate 入口与 READMEcrates/bevy_extract/src/lib.rs、crates/bevy_extract/README.md组件/资源/同步实现extract_component.rs、extract_resource.rs、sync_component.rs、sync_world.rs插件与调度extract_plugin.rs派生宏crates/bevy_extract/macros/src/extract_component.rs渲染侧再导出crates/bevy_render/src/lib.rs【免费下载链接】bevyA refreshingly simple>项目地址: https://gitcode.com/GitHub_Trending/be/bevy创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号