用途
本技能用于指导在 Decentraland SDK7 场景中为文本组件设置字体。每个文本组件有两个字体字段:font 指定内置字体面,fontSrc 指向场景内容中的 .ttf 文件路径。
主要能力
- 内置字体:TextShape / UiText 使用 Font.F_SANS_SERIF(默认)、Font.F_SERIF、Font.F_MONOSPACE;React-ECS props 使用 'sans-serif'(默认)、'serif'、'monospace'。仅这三种内置字体,没有其他字体名列表。
- 自定义字体:fontSrc 是场景根目录相对路径,不是字体名称。支持 TextShape、UiText、UiInput、UiDropdown 以及 React-ECS 的 Label、Button、Input、Dropdown 和 UiEntity uiText。
- 版本要求:fontSrc 需要 7.30.1 之后的第一个 @dcl/sdk 版本。在 7.30.1 及更早版本中该字段不存在,会报 TypeScript 错误,强制绕过类型也不会被发送到浏览器。写 fontSrc 前应从 node_modules/@dcl/sdk/package.json 或 package.json 读取已安装版本;旧场景应升级 SDK 或继续使用内置字体;不要修改 node_modules 中 SDK 生成的序列化器。
- 回退规则:fontSrc 旁必须设置 font 作为回退。移动端始终回退;桌面端在字体资源包就绪前回退。回退应选择最接近的内置字体面:衬线或展示字体用 'serif',代码或终端字体用 'monospace',其余用 'sans-serif'。
- 移动端限制:Decentraland 移动应用不支持自定义字体,始终渲染 font 回退(decentraland/godot-explorer#3092,无预计时间)。所有使用 fontSrc 的场景必须保证回退状态下外观和布局正常:不要依赖自定义字体宽度适配固定框;不要将含义仅放在字体外观中(如图标字体、符号字体、手写线索);应告知用户自定义字体不会在移动端显示。
- 字体文件:自定义字体必须是 .ttf 文件放在场景中。用户指定字体名称(如 "use Playfair Display")时,需要其 .ttf 文件位于场景文件夹并设置 fontSrc;如无 .ttf,应告知用户自定义字体受支持并请其提供 .ttf 文件和许可证,不得自行获取。
- Unity 浏览器兼容性:仅场景内容中的 .ttf 在资源包存在后可用(已部署,或使用优化资源预览)。OpenType with CFF outlines(通常 .otf)、集合(.ttc)、Web 字体(.woff、.woff2)会回退;超过 16 MB 或字形轮廓极其复杂的 .ttf 会回退(转换器拒绝);URL 到 .ttf 会回退;字体家族名(如 'Playfair Display')会回退;缺失文件、无效文件、空字符串会回退。Bevy 浏览器对 URL 和字体家族名支持,其他情况未记录,不应依赖。协议文档注释和编辑器工具提示称字体家族名可用,但那是仅 Bevy 的行为;Unity 出于安全、代码大小、运行时字形栅格化原因有意放弃外部字体。不要在 fontSrc 中写字体家族名或 URL。桌面客户端拒绝字体时会在控制台记录 SDK_FONTS 警告,字体回退时应先检查控制台。
- 添加字体到场景:将 .ttf 放在 assets/fonts/ 下(如 assets/fonts/BungeeShade-Regular.ttf),使用静态 .ttf;如字体家族仅提供可变字体,使用其静态实例。将许可证放在旁边(如 assets/fonts/BungeeShade-OFL.txt);部署会将文件发布到公共内容服务器,许可证必须允许再分发和嵌入,OFL 和 Apache 字体允许,大多数商业桌面许可证不允许。通过场景根目录相对路径引用,与纹理 src 相同:fontSrc: 'assets/fonts/BungeeShade-Regular.ttf'。一个文件是一个字面;粗体标题和常规正文需分别提供两个权重并各自指向文件。
- 性能成本:使用相同 fontSrc 的每个文本实体共享一份已加载副本,场景中复用字体不比使用一次成本更高。每个不同字体文件成为独立资源包,约 700 KB(两个纹理图集),外加内存中自己的纹理。场景应保持一两个字体文件。
- 3D 文本(TextShape)示例:导入 engine、Transform、TextShape、Font 以及 Vector3、Color4、Color3;创建实体并设置 Transform;TextShape.create 设置 text、fontSize、textColor、outlineColor、outlineWidth、font: Font.F_SERIF、fontSrc: 'assets/fonts/AbrilFatface-Regular.ttf';运行时切换字体只需写字段 TextShape.getMutable(sign).fontSrc = 'assets/fonts/BungeeShade-Regular.ttf'。
- UI 文本(React-ECS)示例:Label 设置 value、fontSize、font="sans-serif"、fontSrc="assets/fonts/BungeeShade-Regular.ttf"、uiTransform;Button 设置 value、variant、font、fontSrc;Input 设置 placeholder、font="serif"、fontSrc="assets/fonts/PTSerif-Regular.ttf";Dropdown 设置 options、font、fontSrc;UiEntity 使用 uiText={{ value: 'Coded-only text bag', font: 'monospace', fontSrc: 'assets/fonts/AzeretMono-Medium.ttf' }}。
- 可编辑 UI(build-ui):字面 fontSrc 字符串符合可编辑契约,但 Creator Hub UI Designer 是否显示并保留尚未验证。写入后在编辑器中打开组件并检查保存后 prop 是否保留。
- 测试自定义字体:桌面客户端(Unity 浏览器)仅从资源包加载场景字体,从不从原始 .ttf 加载。因此自定义字体仅在资源包存在的地方显示:Creator Hub 中 Play Options → Desktop Client → Compress Assets 的优化资源本地预览,或 CLI 中 npm run start -- --asset-bundles;Desktop Explorer 自行转换场景资源包括字体,需要 v0.189.0 之后的 Desktop Explorer 版本,旧版本转换不出字体包,即使开启 Compress Assets 预览也显示回退。普通本地预览(无优化资源)始终显示字体回退,这是预期行为而非 bug。已部署场景在服务器资源包转换完成后显示字体,之前显示回退;字体转换存在前部署的场景需重新部署才有字体包。Bevy 浏览器直接加载 .ttf,无需转换即可预览显示。移动应用始终回退。用户报告“字体不工作”前应告知适用情况。参考场景为 decentraland/sdk7-test-scenes 中的 scenes/84,-6-font-src(区域 sdk7testscenes.dcl.eth 的 realm),覆盖各回退情况、组件间共享字体、重建组件和场景边界。
- 字形与可读性:自定义字体只绘制其包含的字符,缺失字符会以内置 sans-serif 在词中间绘制,看起来像损坏。重音字母、西里尔文、CJK 等应选择包含这些脚本的字体。字体包预渲染 ASCII、智能标点(引号、破折号、省略号、项目符号)、€ 和常见 Latin-1 字母;字体包含的其他字符(西里尔文、希腊文、CJK 等)首次出现时渲染,会造成短暂卡顿;这些脚本的文本应尽早显示(加载或介绍屏幕)而非关键时刻。任何文本值都不要使用 emoji,Unity 浏览器没有 emoji 字形。装饰性和展示字体仅用于短标题和标志;正文和移动中阅读的内容需要朴素字体,字号参见 build-ui(UI)和 advanced-rendering(3D)。等宽字体(内置或自定义)不会使 TextShape 中空格对齐列,应每列使用一个 TextShape。
使用方式
确定内置或自定义字体;自定义字体需检查 SDK 版本、放置 .ttf 和许可证、设置 font 回退和 fontSrc 路径;按测试条件验证显示。
适用场景
Decentraland SDK7 场景中需要为 3D 文本或 UI 文本设置内置或自定义字体的开发场景。
限制
移动端不支持自定义字体;Unity 浏览器仅支持场景内容中的 .ttf 且需资源包;不支持 .otf、.ttc、.woff、.woff2、URL 或字体家族名;字体包约 700 KB,建议场景仅一两个字体文件;字符覆盖有限;无 emoji;等宽字体不实现列对齐。字体是否支持 Creator Hub UI Designer 的显示与保留尚未验证。