Bevy 0.20 迁移指南:TextFont 默认字号改为 FontSize::Rem(1.),让 RemSize 真正成为根字号

发布时间:2026/11/5 10:29:17

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/10/24 14:03:22

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

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

2026/11/4 7:38:16

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

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

2026/11/5 10:28:52

C/C++的OpenCV实现模板匹配的基础实现与优化

前言 模板匹配(template matching)是图像处理里最直观的定位手段:拿一张小图(模板)在一张大图(待搜索图)上逐位置滑动,计算每个位置的相似度,相似度最高的位置就是匹配结…

2026/11/5 10:28:52

MCP协议:大模型接口标准化的工程实践

1. 项目概述:大模型时代的接口标准化革命 去年在部署一个跨平台AI应用时,我不得不为同一个功能分别适配OpenAI、Claude和本地部署的Llama模型。每种模型都有独特的API规范、参数格式和返回结构,光是协议转换就占用了60%的开发时间。这种碎片化…

2026/11/5 10:28:52

使用Traefik与Bright Data构建高匿名数据采集系统

1. 项目背景与核心价值数据采集是现代互联网业务中不可或缺的一环,无论是市场调研、竞品分析还是舆情监控,都需要高效可靠的数据获取能力。Bright Data的MCP(Mobile Carrier Proxy)作为一种移动运营商代理解决方案,能够…

2026/11/5 10:28:52

AMIE如何让大模型学会主动问诊:从答题到对话诊疗的技术拆解

医学问诊这件事,长期以来被认为是人工智能最难啃的骨头之一。不是因为它需要多深的算力,而是因为它同时要求模型具备长程对话记忆、多模态信息整合、鉴别诊断推理,以及在信息不完整时主动追问的能力。过去几年里,各类模型在静态医…

2026/11/5 10:28:52

Windows入侵痕迹分析与安全加固实战指南

1. 事件响应与入侵排查基础认知当服务器或工作站出现异常行为时,专业的安全工程师会像数字侦探一样开展调查。最近处理的一起企业内网入侵事件中,攻击者通过钓鱼邮件获取初始权限后,在Windows Server 2019系统上建立了持久化通道。通过系统日…

2026/11/5 10:23:51

AGI时代智慧主权与《全球智慧文明宪章》技术解析

1. 项目背景与核心议题 2026年AGI(通用人工智能)技术突破临界点,全球范围内出现首个通过图灵测试的自主意识体。这一里程碑事件引发各国对"智慧主权"概念的激烈辩论——当AI系统具备自我意识后,其创造者、部署国是否天然…

2026/11/4 12:38:23

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/4 21:04:25

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/5 0:02:07

多智能体协作系统架构设计与实践优化

1. 多智能体协作系统的时代背景2017年Transformer架构的诞生彻底改变了人工智能的发展轨迹。当行业还沉浸在单一大模型带来的性能突破时,Anthropic的研究团队已经将目光投向了更前沿的领域——如何让多个智能体通过协作产生超越单体能力的系统智能。这就像交响乐团中…

2026/11/5 0:02:07

大模型系统性入门实战指南:从原理到部署微调的全链路路线

提到大模型的系统性入门,我先说个结论:这事真不难,难的是资料太散、路线太多,今天这个框架明天那个工具,新人很容易在“收藏夹吃灰”和“教程看到一半放弃”之间反复横跳。市面上关于大模型的内容少说有几十万篇&#…

2026/11/5 0:02:07

鸿蒙文件系统沙箱机制解析与开发实践

1. 鸿蒙文件系统沙箱机制深度解析作为一名从Android转向鸿蒙开发的工程师,我深刻体会到文件系统访问是迁移过程中最先遇到的"拦路虎"。在Android上运行良好的文件读写代码,在鸿蒙真机环境却频频出现文件写入后神秘消失或直接抛出权限拒绝错误的…

2026/11/4 12:38:23

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/4 21:04:25

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑