Bevy 0.19 UI Feature 拆分与渲染陷阱
问题现象
在 Bevy 0.19 中,如果 Cargo.toml 的 dev-dependencies 里只启用 "bevy_ui" 而遗漏 "bevy_ui_render",UI 布局系统会正常工作(Node 实体存在、布局计算正确),但屏幕上完全不渲染任何 UI 元素——包括文本、背景色、边框。
更隐蔽的是,如果此时还使用 FontSource::SystemUi 而未启用 system_font_discovery feature,文本测量会返回 NoSuchFont 错误,导致文本尺寸为 0,进一步掩盖问题。
根因
Bevy 0.19 将 UI 系统拆分为更细粒度的 feature:
| Feature | 职责 | 遗漏后果 |
|---|---|---|
bevy_ui | 布局系统(Node、Flex、Grid、事件) | 无法使用 UI 组件 |
bevy_ui_render | 渲染提取管线(将 UI 节点绘制到屏幕) | UI 有布局但不显示 |
system_font_discovery | 系统字体数据库(Parley backend) | FontSource::SystemUi 无法解析 |
关键发现路径
- Sprite 显示,UI 不显示 → 2D 渲染管线正常,问题在 UI 提取
- 红色矩形显示,文本不显示 →
bevy_ui_render已加载,但文本测量失败 - 改用
TextFont::from_font_size()(内置字体)后文本显示 → 确认SystemUi需要system_font_discovery
修复方案
Cargo.toml
[dev-dependencies]
bevy = { version = "0.19.0-rc.1", default-features = false, features = [
# ... 其他 features ...
"bevy_ui",
"bevy_ui_render", # ← 必须显式启用
# ...
] }代码层
// 使用内置默认字体(不需要 system_font_discovery)
let text_font = TextFont::from_font_size(40.);
// 错误:SystemUi 需要 system_font_discovery feature
// let text_font = TextFont {
// font: FontSource::SystemUi,
// ..default()
// };诊断流程
遇到 UI 不显示时,按此顺序排查:
-
确认
bevy_ui_renderfeature 已启用- 检查
Cargo.toml - 无此 feature = 什么都不显示
- 检查
-
确认
bevy_text和default_fontfeature 已启用- 或使用
asset_server.load("fonts/...")加载自定义字体
- 或使用
-
如果使用系统字体,确认
system_font_discovery已启用- 否则
FontSource::SystemUi/FontSource::SansSerif等会静默失败
- 否则
-
检查相机
- Bevy 0.19 官方 example 使用
commands.spawn(Camera2d); - 不需要
IsDefaultUiCamera(它会自动 fallback 到 primary window 相机)
- Bevy 0.19 官方 example 使用
-
检查布局
Display::Grid需要显式定义grid_template_columns/rowsPositionType::Absolute的容器需要显式width/height
版本对比
| 版本 | UI 渲染 feature | 内置字体 feature | 系统字体 |
|---|---|---|---|
| 0.18 | bevy_ui 隐式包含渲染 | default_font(默认启用) | 未分离 |
| 0.19 | bevy_ui + bevy_ui_render 分离 | default_font(仍默认) | 需 system_font_discovery |
实战教训
bevy_http_client example 修复案例
- 原始代码:
Display::Grid+Node::default()嵌套 +bevy_uionly - 现象:画面空白,没有任何 UI
- 修复步骤:
Cargo.toml添加"bevy_ui_render"Display::Grid→Display::Flex- 移除
Node::default()嵌套(Text 直接作为 flex 子项) - 改用
TextFont::from_font_size()使用内置字体 - 移除多余的
IsDefaultUiCamera
通用检查清单
-
Cargo.toml中"bevy_ui_render"已显式列出 - 如果使用自定义 feature set,
"bevy_text"和"default_font"已启用 - 如果使用系统字体,
"system_font_discovery"已启用 - 相机使用
Camera2d(无需IsDefaultUiCamera) - 布局容器有显式尺寸(
width/height或aspect_ratio)
相关页面
- bevy-migration-2026-05 — 0.19 完整迁移跟踪
- bevy-ui-text — UI 文本系统概念
- bevy-development-patterns — Bevy 开发模式汇总