发布时间:2026/9/6 19:28:12
Bevy 0.20 迁移指南:TextFont 默认字号改为 FontSize::Rem(1.),让 RemSize 真正成为根字号 Bevy 0.20 迁移指南TextFont 默认字号改为 FontSize::Rem(1.)让 RemSize 真正成为根字号【免费下载链接】bevyA refreshingly simple>项目地址: https://gitcode.com/GitHub_Trending/be/bevy本文基于 Bevy 仓库中的官方迁移文档 default_font_size_is_rem.md 展开讲清 0.20 版本中TextFont::default()默认字号从FontSize::Px(20.)变为FontSize::Rem(1.)的动机与行为差异并结合 bevy_text 与 bevy_ui 的源码说明RemSize资源如何参与字号求值与重排最后给出保持固定字号与跟随根字号缩放两种迁移写法。读完后你能判断自己的文本代码在 0.20 下是否需要改动以及改动点应该写在哪里。一、变更内容默认字号从固定 20px 变为 1rem迁移文档给出的核心变更只有一句话TextFont::default()now usesFontSize::Rem(1.)instead ofFontSize::Px(20.), so that theRemSizeresource actually sets the default font size.也就是说旧行为0.19 及以前没有显式设置字号的文本字号被硬编码为 20 逻辑像素FontSize::Px(20.)与RemSize资源无关新行为0.20默认字号改为FontSize::Rem(1.)即1 个根字号单位由RemSize资源决定。由于RemSize的默认值恰好是 20 逻辑像素所以在默认配置下渲染结果完全一致但从此以后凡是保持默认字号的文本都会随RemSize的修改而整体缩放。文档给出的迁移建议是如果你希望文本大小固定不变就显式设置像素字号// 0.20 TextFont { font_size: FontSize::Px(20.), ..default() }这个改动是 Bevy 文本子系统 rem/em 单位支持的一部分与同 PR#25231中的另一篇迁移文档 val_em_and_rem.md 描述的Val::Em/Val::Rem变体、EmSize组件、FontSize::eval签名变更共同构成了 0.20 的根字号体系。二、源码印证TextFont::default()现在返回 Rem(1.)在 crates/bevy_text/src/text.rs 中TextFont的Default实现已经落实了这一变更impl Default for TextFont { fn default() - Self { Self { font: Default::default(), font_size: FontSize::Rem(1.), style: FontStyle::Normal, weight: FontWeight::NORMAL, width: FontWidth::NORMAL, font_features: FontFeatures::default(), font_variations: FontVariations::default(), font_smoothing: Default::default(), } } }需要注意一个容易混淆的细节TextFont的默认字号变了但FontSize枚举自身的Default实现仍然是Px(20.)见 crates/bevy_text/src/text.rsimpl Default for FontSize { fn default() - Self { Self::Px(20.) } }因此直接调用TextFont::default()绝大多数 UI/2D 文本路径都走这里得到的是Rem(1.)而单独使用FontSize::default()或..Default::default()展开font_size字段的地方得到的仍是Px(20.)。二者不一致正是这类迁移的常见坑点升级时建议全局搜索FontSize::default()和TextFont::default()确认行为是否符合预期。三、RemSize根字号资源的定义、注册与求值3.1 资源定义与默认值RemSize定义在 crates/bevy_text/src/text.rs/// Default [RemSize] and [EmSize], in logical pixels pub const DEFAULT_REM_SIZE_PX: f32 20.0; /// The root font size, in logical pixels. /// /// Rem units always resolve against this one global resource, including /// FontSize::Rem, LetterSpacing::Rem and Val::Rem. #[derive(Resource, Copy, Clone, Debug, PartialEq, Deref, DerefMut, Reflect)] pub struct RemSize(pub f32); impl Default for RemSize { fn default() - Self { Self(DEFAULT_REM_SIZE_PX) } }要点RemSize(pub f32)是单一全局Resource单位为逻辑像素默认值 20.0 对应常量DEFAULT_REM_SIZE_PX文档注释明确了它的作用域FontSize::Rem、LetterSpacing::Rem和Val::Rem三种 rem 单位都只解析到这一个全局资源该资源由TextPlugin在插件构建时注册init_resource::RemSize()见 crates/bevy_text/src/lib.rs。也就是说只要你的应用启用了文本功能RemSize就可用无需手动注册。3.2FontSize::evalrem 如何变成像素FontSize是文本字号的枚举支持Px、Vw、Vh、VMin、VMax、Rem六种单位定义见 crates/bevy_text/src/text.rs。求值入口是eval方法crates/bevy_text/src/text.rsimpl FontSize { /// Evaluate the font size to a value in logical pixels pub fn eval( self, // Viewport size in logical pixels logical_viewport_size: Vec2, // Base Rem size in logical pixels rem_size: RemSize, ) - f32 { match self { FontSize::Px(s) s, FontSize::Vw(s) logical_viewport_size.x * s / 100., FontSize::Vh(s) logical_viewport_size.y * s / 100., FontSize::VMin(s) logical_viewport_size.min_element() * s / 100., FontSize::VMax(s) logical_viewport_size.max_element() * s / 100., FontSize::Rem(s) rem_size.0 * s, } } }FontSize::Rem(s)的求值就是rem_size.0 * sRem(1.)在当前默认配置下等于20.0 * 1.0 20逻辑像素与旧版的Px(20.)数值相同——这就是迁移文档所说renders identically渲染结果一致的数学依据。另一个值得注意的签名变化0.20 中eval的第二个参数从裸f32改成了RemSize类型。这一点在 val_em_and_rem.md 中有专门记录// 0.19 let size font_size.eval(logical_viewport_size, rem_size_px); // 0.20 let size font_size.eval(logical_viewport_size, RemSize(rem_size_px));如果你自己封装了字号计算逻辑这是需要跟着改的调用点。3.3 渲染管线中的重排机制默认字号变成Rem之后修改RemSize能全局缩放文本这一行为是如何生效的从源码结构看答案在文本管线与重排标记里TextPipeline::update_buffer在遍历每个文本 span 时如果发现字号是 rem 系单位就把该文本块的uses_rem_sizes标记置为 true见 crates/bevy_text/src/pipeline.rsmatch text_font.font_size { crate::FontSize::Vw(_) | crate::FontSize::Vh(_) | crate::FontSize::VMin(_) | crate::FontSize::VMax(_) computed.uses_viewport_sizes true, crate::FontSize::Rem(_) computed.uses_rem_sizes true, _ (), }随后字号通过text_font.font_size.eval(logical_viewport_size, base_rem_size)求值crates/bevy_text/src/pipeline.rs。ComputedTextBlock持有uses_rem_sizes标志crates/bevy_text/src/text.rs其needs_rerender方法会在RemSize发生变化且该文本块使用了 rem 单位时返回 true从而触发重新排版crates/bevy_text/src/text.rspub fn needs_rerender( self, is_viewport_size_changed: bool, is_rem_size_changed: bool, ) - bool { self.needs_rerender || (is_viewport_size_changed self.uses_viewport_sizes) || (is_rem_size_changed self.uses_rem_sizes) }这个设计的实际效果是只有使用了 rem或视口单位的文本才会因RemSize变化而重排纯Px文本不受影响避免不必要的全量重排开销。这也再次说明0.20 之后默认字号的文本天然进入了 rem 依赖集合而显式写成Px的文本则被排除在外——这正是迁移文档推荐固定尺寸请显式写Px的底层原因。四、对 UI 布局与文本输入的影响RemSize不只影响字号本身它已经贯穿 UI 布局链路4.1 UI 节点的font_size转换在 crates/bevy_ui/src/geometry.rs 中Val到FontSize的转换显示未显式设置字号的 UI 节点Val::Auto会被转成FontSize::Rem(1.)Val::Em(em)也会被归一化为FontSize::Rem(em)em 相对于本节点字号解析先折算成 rem 表达Val::Auto FontSize::Rem(1.), Val::Px(px) FontSize::Px(px), Val::Percent(percent) FontSize::Rem(percent / 100.), Val::Rem(rem) FontSize::Rem(rem), Val::Em(em) FontSize::Rem(em), // see comment above也就是说没有手动设置字号的 UI 文本在 0.20 中会统一走 rem 路径这是本次迁移影响面最大的场景。4.2 文本输入组件的重排条件bevy_ui的文本输入布局系统同样感知了这次变化。crates/bevy_ui/src/widget/text_input_layout.rs 中的重排条件明确加入了字号是 rem 且RemSize已变化的分支|| matches!(text_font.font_size, FontSize::Rem(_)) rem_size.is_changed()并在光标宽度等计算中直接用text_font.font_size.eval(target.logical_size(), *rem_size)求值同文件 L515。所以基于TextInput的组件在RemSize变化时也会正确跟随缩放。4.3 同 PR 的其他连带变更由于 rem 求值需要根字号 节点字号两个输入同一 PR 还带来了 val_em_and_rem.md 记录的 API 变更做 0.20 升级时应一并检查Val、Val2、UiPosition、CornerRadius、RadialGradientShape、UiTransform::compute_affine、BorderRadius的resolve/compute_affine方法新增em_size: EmSize与rem_size: RemSize两个参数ComputedNode新增em_size、rem_size字段用于记录布局时实际采用的字号方便下游如 box shadow复用Node现在要求EmSize组件从bevy_text导出、经bevy_ui::prelude可用节点有TextFont时会在TextFont、RemSize或渲染目标信息变化时自动重算EmSize没有TextFont时该值由应用自行维护默认值为DEFAULT_REM_SIZE_PX20 逻辑像素且不跟随RemSize的后续变化——需要跟随根字号的布局值应使用Val::Rem。五、迁移实操如何写代码5.1 场景一保持固定字号推荐大多数游戏 UI如果你的文本尺寸是美术规格定的固定像素按迁移文档显式写死即可use bevy::prelude::*; fn setup(mut commands: Commands) { commands.spawn(Text2d::new(Hello Bevy 0.20)).insert(TextFont { font_size: FontSize::Px(20.), ..default() }); }也可以走链式构造器TextFont::from_font_size/with_font_size见 crates/bevy_text/src/text.rs例如TextFont::from_font_size(20_f32)会构造出Px语义的字号。仓库示例中的既有写法本身就是这种风格如 examples/2d/text2d.rs 里的font_size: FontSize::Px(50.0)、examples/2d/texture_atlas.rs 中的FontSize::Px(42.0)这些文本在 0.20 中行为不变。5.2 场景二让文本跟随根字号缩放如果你希望做全局字号调节例如设置面板里的 A/A 选项、高分辨率适配现在只需修改RemSize所有保持默认或显式Rem的文本会自动重排fn change_root_font_size(mut rem_size: ResMutRemSize) { rem_size.0 32.0; // 所有 Rem(1.) 的默认文本变为 32 逻辑像素 }生效链路是RemSize变化 → 使用 rem 字号的文本块needs_rerender为 truecrates/bevy_text/src/text.rs→ 文本管线按rem_size.0 * s重新求值并排版crates/bevy_text/src/pipeline.rs。注意一个行为差异在旧版本中同样的操作对默认文本完全无效因为默认就是Px(20.)升级后同一份代码里没写字号的文本会开始响应RemSize。如果你在旧代码里依赖过默认文本不会缩放这一事实需要在 0.20 中显式补上FontSize::Px。5.3 相关示例参考examples/2d/text2d.rs2D 文本示例演示显式FontSize::Px的常规写法examples/ui/text/letter_spacing.rs展示了RemSize与LetterSpacing::Rem/LetterSpacing::Px之间的换算方式LetterSpacing::Rem(v / rem_size.0)是理解一切 rem 单位都以RemSize为基准的良好参考。六、小结项目0.19 及以前0.20TextFont::default()的字号FontSize::Px(20.)FontSize::Rem(1.)FontSize::default()FontSize::Px(20.)仍为FontSize::Px(20.)默认RemSize—对默认字号无作用20.0逻辑像素且真正决定默认字号修改RemSize的影响不影响默认字号文本所有默认/Rem字号文本重排缩放保持固定尺寸的写法不写即可显式TextFont { font_size: FontSize::Px(20.), ..default() }本次变更本质上是把 Bevy 文本系统的根字号概念补齐RemSize从仅供显式Rem单位使用的资源升级为所有默认文本字号的真正来源并在渲染管线中通过uses_rem_sizes标记实现了按需重排。升级 0.20 时的检查清单很简单确认默认字号文本是否需要固定需要则显式写Px检查自定义代码中FontSize::eval、Val::resolve等 API 调用是否补上了RemSize/EmSize参数以及留意 val_em_and_rem.md 中Node对EmSize的新要求。【免费下载链接】bevyA refreshingly simple>项目地址: https://gitcode.com/GitHub_Trending/be/bevy创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

2026/9/6 19:28:12

DO-160G中文版实操指南:机载设备环境试验与适航认证要点解析

简介:RTCA DO-160G是国际航空界广泛采用的机载设备环境条件和试验程序标准,本资料为该标准的中文版PDF文档,适合航电系统设计、环境可靠性试验与适航验证相关工程技术人员研读参考。文件为单份高清PDF,体积7.55MB,共1个…

2026/9/6 19:28:12

嘉格纳DF480161CN全嵌入式洗碗机快速说明书核心要点与使用指南

简介:《Gaggenau嘉格纳DF480161CN洗碗机快速说明书》是一份面向该型号洗碗机用户与安装维护人员的官方快速参考文档,针对安装尺寸、水电连接、洗涤模式选择、日常清洁保养及常见故障诊断等实际操作问题给出简洁指引。资源为一个独立的PDF文件&#xff0c…

2026/9/6 20:23:14

两级全差分高增益放大器设计:从指标分解到流片实战

简介:面向模拟集成电路学习者的设计参考文档,以两级全差分高增益放大器为设计对象,完整覆盖从性能指标设定、电路结构选型、参数计算到前仿真、版图绘制与物理验证的模拟IC全流程。文档基于华大九天Aether平台与0.18um PDK,针对DC…

2026/9/6 20:23:14

IOPaint完整指南:几步搞定图片去水印与路人消除

IOPaint完整指南:几步搞定图片去水印与路人消除 【免费下载链接】IOPaint Image inpainting tool powered by SOTA AI Model. Remove any unwanted object, defect, people from your pictures or erase and replace(powered by stable diffusion) any thing on you…

2026/9/6 20:23:14

开关电源并联供电系统实战:UC3843与LM358均流设计

简介:2011年全国大学生电子设计竞赛A题“开关电源并联供电系统”的完整设计报告,适合电子设计竞赛备赛学生、开关电源入门开发者参考。压缩包为1个doc文档,大小255KB,目前已获317人学习浏览。报告系统梳理了从方案论证到指标测试的…

2026/9/6 20:23:14

Fluent燃烧算例调参指南:从模型选型到收敛控制的完整路径

简介:《Fluent燃烧算例详细教程》是一份面向Fluent燃烧仿真场景的中文PDF技术资料,适合需要处理燃烧、湍流与反应流计算问题的工程师和科研人员。文档系统梳理了燃烧模型、湍流模型、燃烧反应模型以及计算流体力学仿真四个核心模块,重点介绍了…

2026/9/6 20:23:14

微信聊天记录导出成HTML、Word、CSV:WeChatMsg 三步完整指南

微信聊天记录导出成HTML、Word、CSV:WeChatMsg 三步完整指南 【免费下载链接】WeChatMsg 提取微信聊天记录,将其导出成HTML、Word、CSV文档永久保存,对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we…

2026/9/6 0:06:59

超人会飞不算本事:系统稳定依赖清晰规则与边界设计

开头先不绕弯子。“#斯坦李吐槽dc 所以超人是无缘无故会飞的嘛哈哈哈哈哈哈哈锤哥真是技术人才啊!#雷神 #复联”这类调侃式短标题,第一波冲击力在于它把两个宇宙的角色塞进同一个吐槽箱里,但细想一下就能发现,它真正碰到的根本不是…

2026/9/6 0:06:59

超人VS蜘蛛侠:拆解超级IP的影响力与传播方法论

把“蜘蛛侠 vs 超人”放在 CSDN 上聊,可能很多人第一反应是走错片场了。但如果把这两个角色看成“两个持续运营了 80 多年的文化产品”,你会发现,这场比较本质上是两个不同 IP 策略的长期结果对比:超人赢在定义了整个超级英雄题材…

2026/9/6 0:06:59

基于CNN的调制信号识别:MATLAB实现时频图分类实战

简介:本资源是一套面向通信工程与信号处理方向学习者、研究者的深度学习实践方案,聚焦调制信号自动检测与识别这一典型无线通信任务,解决传统方法依赖人工特征、低信噪比下性能下降等痛点。压缩包共12个文件(10.73MB)&…

2026/9/6 0:06:59

超人会飞不算本事:系统稳定依赖清晰规则与边界设计

开头先不绕弯子。“#斯坦李吐槽dc 所以超人是无缘无故会飞的嘛哈哈哈哈哈哈哈锤哥真是技术人才啊!#雷神 #复联”这类调侃式短标题,第一波冲击力在于它把两个宇宙的角色塞进同一个吐槽箱里,但细想一下就能发现,它真正碰到的根本不是…

2026/9/6 0:06:59

超人VS蜘蛛侠:拆解超级IP的影响力与传播方法论

把“蜘蛛侠 vs 超人”放在 CSDN 上聊,可能很多人第一反应是走错片场了。但如果把这两个角色看成“两个持续运营了 80 多年的文化产品”,你会发现,这场比较本质上是两个不同 IP 策略的长期结果对比:超人赢在定义了整个超级英雄题材…

2026/9/6 0:06:59

基于CNN的调制信号识别:MATLAB实现时频图分类实战

简介:本资源是一套面向通信工程与信号处理方向学习者、研究者的深度学习实践方案,聚焦调制信号自动检测与识别这一典型无线通信任务,解决传统方法依赖人工特征、低信噪比下性能下降等痛点。压缩包共12个文件(10.73MB)&…

2026/9/6 11:40:10

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/6 19:33:50

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/6 10:19:40

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…