文本元素
文本元素通过字体资源绘制字符串。画布内的标签、标题、分数、对话和其他文字都是文本元素。
创建文本
- 引擎
- 编辑器
- React
- Web Components
const title = new pc.Entity('title');
title.addComponent('element', {
type: pc.ELEMENTTYPE_TEXT,
fontAsset: font.id,
text: 'Game Over',
fontSize: 64,
color: new pc.Color(1, 0.55, 0.2),
anchor: [0.5, 0.5, 0.5, 0.5],
pivot: [0.5, 0.5]
});
screen.addChild(title);
font 是已加载的字体资源,详见使用字体资源。
选中屏幕或元素,在层级面板单击 +,选择 User Interface › Text Element。将 Font 设为字体资源,再配置 Text、Font Size 和 Color。在 Text 中按 Shift+Enter 可换行。
<Entity name="title">
<Element type="text" fontAsset={font} text="Game Over" fontSize={64} color="#ff8c33"
anchor={[0.5, 0.5, 0.5, 0.5]} pivot={[0.5, 0.5]} />
</Entity>
font 是 useFont 返回的资源。
<pc-entity name="title">
<pc-element type="text" font-asset="arial" text="Game Over" font-size="64" color="#ff8c33"
anchor="0.5 0.5 0.5 0.5" pivot="0.5 0.5"></pc-element>
</pc-entity>
arial 是 <pc-asset type="font"> 的 id。
字体中不存在的字符会显示为空格,引擎同时记录指出该字符的警告。创建字体资源时,应包含文本需要的全部字符,详见选择字符。
字号、间距与对齐
| 属性 | 效果 |
|---|---|
fontSize | 以屏幕单位表示的文本高度,默认为 32 |
lineHeight | 相邻行基线的距离。创建时设置了 fontSize 但未设置 lineHeight,则行高等于字号;之后修改 fontSize 不会同步修改行高 |
spacing | 字符间距倍率,默认为 1 |
alignment | 文本在元素内的位置,从左下角 0, 0 到右上角 1, 1,默认 0.5, 0.5 居中 |
只有元素大于文本时,对齐效果才明显,例如固定宽度标签,或长度不同的多行文本。
尺寸、换行与行数限制
默认情况下,Auto Width 和 Auto Height 会在文本变化时使元素宽高适应文本。关闭它们后,可指定元素尺寸。
启用 Wrap Lines 且元素具有约束宽度时,文本会自动换行:需关闭 Auto Width,或使用水平分离锚点从锚点取得宽度。启用 Auto Height 时,行数增加会使元素变高。
// A paragraph that wraps at 400 units and grows downwards from its top edge
paragraph.element.autoWidth = false;
paragraph.element.width = 400;
paragraph.element.wrapLines = true;
paragraph.element.pivot = new pc.Vec2(0.5, 1);
maxLines 限制行数,但超出的文字不会被直接截断,而会继续排在最后一行并越过元素边界。因此应搭配缩小适配,或通过遮罩裁切。布局完成后,lines 数组保存各行字符串。
缩小适配
Auto Fit Width 和 Auto Fit Height 会在 Max Font Size 与 Min Font Size 之间缩小字体,默认上限 32、下限 8。能放下时使用最大字号;即使最小字号仍放不下时,则保持最小字号并溢出。行高随字号一起缩小。
自动适配仅在对应轴的自动尺寸关闭时生效:Auto Fit Width 要求关闭 Auto Width,Auto Fit Height 要求关闭 Auto Height。否则元素本身会变大以适应文本。
// Shrink a name to fit its 200 × 40 badge, down to 12 units if needed
badge.element.autoWidth = false;
badge.element.autoHeight = false;
badge.element.width = 200;
badge.element.height = 40;
badge.element.autoFitWidth = true;
badge.element.autoFitHeight = true;
badge.element.maxFontSize = 32;
badge.element.minFontSize = 12;
两端对齐
启用 Justify 后,通过增大词间距,将自动换行的文本行拉伸到元素两侧。段落最后一行及显式换行结束的行仍保持原对齐。必须同时启用 Wrap Lines。justify 从引擎 2.22 起可用。
描边与阴影
| 属性 | 效果 |
|---|---|
outlineColor 和 outlineThickness | 字符轮廓描边,厚度范围为 0(无)到 1 |
shadowColor 和 shadowOffset | 字符下方的阴影,偏移使用 pc.Vec2,各分量范围为 -1 到 1 |
描边和阴影由字体着色器绘制,适用于编辑器和 font-tools 创建的 MSDF 字体资源。
标记
启用 Enable Markup 后,引擎和 React 使用 enableMarkup,Web Components 使用 enable-markup,文本中的标签可为部分文字设置样式:
| 标签 | 效果 |
|---|---|
[color="#ff0000"]…[/color] | 使用六位十六进制颜色绘制文本,替代该部分的元素颜色 |
[outline color="#000000" thickness="0.5"]…[/outline] | 为文本描边 |
[shadow color="#000000" offset="0.5"]…[/shadow] | 添加阴影,可通过 offsetX 和 offsetY 分别设置两轴 |
message.element.enableMarkup = true;
message.element.text = 'You found the [color="#ffcc00"]golden key[/color]!';
要显示不表示标签起点的 [,请写成 \[。标记存在未闭合等错误时,整个文本会按原样显示,包括标签,引擎同时记录警告。
逐字显示
rangeStart 与 rangeEnd 控制仅绘制一部分文本,范围包含起点而不包含终点。修改它们不会重新布局,因此打字机效果开销很低。修改 text 会将范围重置为整个新文本,此时也可从范围获取长度:
dialog.element.text = 'It is dangerous to go alone.';
// Changing the text resets the range, so rangeEnd is now its length
const length = dialog.element.rangeEnd;
let shown = 0;
const handle = app.on('update', (dt) => {
// Reveal 20 characters a second
shown = Math.min(shown + dt * 20, length);
dialog.element.rangeEnd = Math.floor(shown);
if (shown === length) handle.off();
});
运行时修改文本
设置 text 会重新布局并重建网格,比移动或改色开销更高。每帧更新计时器、分数等少量标签没有问题;大量标签应仅在值变化时更新。详见绘制顺序与性能。
要按玩家语言显示文本,应给元素设置本地化键,而非直接指定文本,详见本地化。
从右到左及复杂文字
文本元素从左到右为每个字符绘制一个字形。阿拉伯语、希伯来语等从右到左书写的语言需要先重排字符,阿拉伯语还需要处理连写字形。接入方法详见语言说明。
另请参阅
- 字体:创建字体资源与选择字符。
- 本地化:按玩家语言显示文本。
- Element 组件、
<pc-element>和 ElementComponent:全部文本属性参考。