跳到主要内容

字体

文本元素通过字体资源绘制文字。资源由描述字形的 .json 和保存字形的一张或多张 .png 纹理页组成,采用多通道有符号距离场(MSDF)。字形保存为距离场而非普通像素,因此不同字号均可保持清晰,每种字体只需一份资源。

创建字体资源​

在编辑器中​

上传 .ttf、.ttc、.otf 或 .dfont 文件。编辑器在浏览器中生成字体,并创建包含源文件、.json、.png 纹理页及字体资源本身的文件夹。

选中字体资源后,在检查器中选择字符。CHARACTER PRESETS 可加入 Latin、Latin Supplement、Cyrillic 和 Greek 等字符集;CUSTOM CHARACTER RANGE 通过十六进制 Unicode 码点加入范围;Characters 列出将包含的字符。单击 REGENERATE FONT ASSETS 重新生成。如果源字体缺少某些字符,检查器会列出,并提供复制字符或编码的按钮。

旧版编辑器创建的字体在首次重新生成时会转换为当前格式,此过程不可撤销。其他选项详见字体资源检查器。

使用 font-tools​

不使用编辑器时,可以通过编辑器自身使用的生成器 font-tools 创建:

  • Web 应用。 打开 playcanvas.github.io/font-tools,拖入 TTF 或 OTF,选择字符与字形尺寸,以实际 PlayCanvas 文本预览结果并下载文件。全部在浏览器中运行,不上传字体。

  • 命令行。 从终端生成资源:

    npx @playcanvas/font-tools MyFont.ttf --charset latin-ext -o assets/fonts/myfont

    此命令写入 myfont.json 和 myfont.png。字符较多时会生成 myfont1.png、myfont2.png 等额外页。

选项默认值效果
-o, --out <path>字体名称不含扩展名的输出路径
--charset <spec>ascii预设 ascii、latin、latin-ext、cyrillic、greek,或直接指定字符
--size <px>64图集中每个字形单元的尺寸
--pxrange <px>8MSDF 距离范围,单位为像素
--name <face>输出名称写入 .json 的字体名称
--no-kerning启用字偶距不包含字偶距数据

font-tools 默认读取字偶距对,编辑器则不会,因此 font-tools 资源的文本间距可能略紧。该工具以 MIT 许可开源,还提供 JavaScript API,可集成到自己的工具中。

选择字符​

字体资源仅包含生成时选择的字符,其他字符会显示为空格并产生控制台警告。应包含全部所需字符,包括重音字母、“” 和 … 等标点、货币符号,以及所有本地化语言的字符。

每个字符都会占用图集空间。中文、日文和韩文所需的数千字符会使资源增大、加载变慢。宜只纳入实际使用的字符,而非整个文字系统;各语言字符集差异较大时,使用独立本地化字体。

使用字体资源​

将 .json 与 .png 页放在一起,并保持相同基础文件名。加载器会根据 JSON URL 推导各页 URL,并一起加载。

// Loading myfont.json also loads myfont.png, and any further pages
const font = new pc.Asset('myfont', 'font', { url: 'fonts/myfont.json' });
app.assets.add(font);
await new Promise((resolve) => {
font.ready(resolve);
app.assets.load(font);
});

const label = new pc.Entity('label');
label.addComponent('element', {
type: pc.ELEMENTTYPE_TEXT,
fontAsset: font.id,
text: 'Hello, World!',
anchor: [0.5, 0.5, 0.5, 0.5],
pivot: [0.5, 0.5]
});
screen.addChild(label);

创建应用时注册 pc.FontHandler,以支持字体加载。

表情​

MSDF 字形只有单色,不能绘制彩色表情。尚未收录于 API 参考的 pc.CanvasFont 可使用浏览器字体,将文字及表情绘入纹理。它属于位图字体,创建尺寸应至少等于最终字号,并在使用前加入所需字符:

const emojiFont = new pc.CanvasFont(app, {
fontName: 'Arial',
fontSize: 64,
color: new pc.Color(1, 1, 1),
width: 256,
height: 256
});
emojiFont.createTextures('Well done! 🎉');

const message = new pc.Entity('message');
message.addComponent('element', {
type: pc.ELEMENTTYPE_TEXT,
text: 'Well done! 🎉',
fontSize: 32,
anchor: [0.5, 0.5, 0.5, 0.5],
pivot: [0.5, 0.5]
});
message.element.font = emojiFont;
screen.addChild(message);

首次 createTextures 创建纹理。设置包含新字符的文本前,应先通过 updateTextures 加入这些字符。

文本表情

另请参阅​