Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

RichTextLabel 中的 BBCode

介绍

Label 节点非常适合显示基础文本,但有一定局限性。如果你需要改变文本的颜色或其对齐方式,则只能对整个标签执行此操作。你不能使文本的一部分具有其他颜色,也不能使文本的一部分居中。要绕过这些限制,你可以使用 RichTextLabel

RichTextLabel 允许使用标记语法或内置 API 对文本进行复杂的格式设置。它使用 BBCode 作为标记语法,这是一个为文本的一部分指定格式规则的标签系统。如果你曾经使用过论坛,你可能对它们很熟悉。(“BBCode” 中的 “BB”(bulletin boards),就是指“公告板”)。

与 Label 不同,RichTextLabel 还带有自己的垂直滚动条。如果文本不适合控件的大小,则会自动显示此滚动条。可以通过在 RichTextLabel 的检查器中取消选中 Scroll Active 属性来禁用滚动条。

需要注意的是,BBCode 标签在一定程度上也可以用于其他场景:

参见

你可以通过 Rich Text Label with BBCode demo project 来直观地看看 RichTextLabel 中的 BBCode 实际是如何运作的。

使用 BBCode

默认情况下,RichTextLabel 的功能和一个普通的 Label 一样。它拥有一个 text 属性,你可以编辑它来显示统一格式的文本。如果想要使用 BBCode 来实现富文本排版,你需要通过设置 bbcode_enabled 来开启 BBCode 模式。开启之后,你就可以在 text 属性中使用各种可用的标签了。选中 RichTextLabel 节点后,这两个属性都位于检查器(Inspector)的最上方。

../../_images/bbcode_in_richtextlabel_inspector.webp

例如, BBCode [color=green]test[/color] 会将单词 "test" 渲染成绿色。

../../_images/bbcode_in_richtextlabel_basic_example.webp

大多数 BBCode 都由三部分组成:开始标签、内容和结束标签。开始标签用来划定格式化内容的起始位置,并且可以附带一些配置选项。像上面展示的那个 color (颜色)标签,它的开始标签就需要搭配一个具体的值才能生效。还有一些开始标签可以接受多个选项(在开始标签内部用空格隔开即可)。结束标签则用来划定格式化内容的结束位置。在某些特定情况下,结束标签和内容部分是可以省略的。

与 HTML 中的 BBCode 不同,RichTextLabel 在显示文本时,并不会自动去除开头或结尾的空白字符。最终输出的内容中,连续重复的空格也会被原样显示出来。这意味着,当你在 RichTextLabel 中展示代码块时,完全不需要额外使用‘预格式化文本’(preformatted text)标签来保留格式。

[tag]content[/tag]
[tag=value]content[/tag]
[tag option1=value1 option2=value2]content[/tag]
[tag][/tag]
[tag]

备注

RichTextLabel 不支持相互嵌套(或交错)的 BBCode 标签。例如,不要这样写:

[b]bold[i]bold italic[/b]italic[/i]

请使用:

[b]bold[i]bold italic[/i][/b][i]italic[/i]

安全地处理用户输入

在用户可以自由输入文本的场景下(比如多人游戏的聊天系统),你应该确保用户无法随意输入能被 RichTextLabel 解析的 BBCode 标签。这是为了避免格式被不当利用,特别是当你的 RichTextLabel 支持处理 [url] 标签时,这可能会带来安全隐患(比如玩家可能会创建出指向钓鱼网站或类似恶意页面的可点击链接)。

利用 RichTextLabel 自带的 [lb] 和(或) [rb] 标签,我们可以把消息里任意 BBCode 标签的左括号和(或)右括号替换成这两个转义标签。这样一来,就能防止用户输入被系统当成真正的 BBCode 标签去解析,而是直接作为普通的纯文本显示出来。

未转义的用户输入导致 BBCode 注入的示例(第 2 行),以及经过转义处理的用户输入示例(第 3 行)

未转义的用户输入导致 BBCode 注入的示例(第 2 行),以及经过转义处理的用户输入示例(第 3 行)

创建一个 Node 节点并附加下面的脚本:

extends RichTextLabel

func _ready():
    append_chat_line("Player 1", "Hello world!")
    append_chat_line("Player 2", "Hello [color=red]BBCode injection[/color] (no escaping)!")
    append_chat_line_escaped("Player 2", "Hello [color=red]BBCode injection[/color] (with escaping)!")


# Returns escaped BBCode that won't be parsed by RichTextLabel as tags.
func escape_bbcode(bbcode_text):
    # We only need to replace opening brackets to prevent tags from being parsed.
    return bbcode_text.replace("[", "[lb]")


# Appends the user's message as-is, without escaping. This is dangerous!
func append_chat_line(username, message):
    append_text("%s: [color=green]%s[/color]\n" % [username, message])


# Appends the user's message with escaping.
# Remember to escape both the player name and message contents.
func append_chat_line_escaped(username, message):
    append_text("%s: [color=green]%s[/color]\n" % [escape_bbcode(username), escape_bbcode(message)])

剥离 BBCode 标签

在某些特定的使用场景下,你可能需要从字符串中把 BBCode 标签给去掉。比如,当你想把 RichTextLabel 里的文本显示在另一个不支持 BBCode 的控件中时(比如显示一个鼠标悬停提示框/tooltip),这个操作就非常有用了。

extends RichTextLabel

func _ready():
    var regex = RegEx.new()
    regex.compile("\\[.*?\\]")
    var text_without_tags = regex.sub(text, "", true)
    # `text_without_tags` contains the text with all BBCode tags removed.

备注

对于用户的输入内容,完全不建议直接删掉所有的 BBCode 标签。因为这样做可能会改变用户原本想显示的文字,而且用户根本不知道为什么自己消息的一部分凭空消失了。相反,更推荐的做法是对用户输入进行转义处理(具体操作可以参考: Escaping user input )。

性能

在大多数情况下,你可以直接使用 BBCode,因为文本格式化通常算不上什么繁重的任务。不过,如果遇到特别庞大的 RichTextLabel(比如长达数千行的控制台日志),当更新其文本内容时,你可能会在游戏中遇到卡顿现象。

有几种方法可以缓解这个问题:

  • 请使用 append_text() 函数,而不是直接往 text 属性里追加内容。因为这个函数只会解析你新添加的那部分文本的 BBCode,而不是把整个 text 属性里的所有 BBCode 重新解析一遍。

  • 使用 push_[tag]()pop() 函数来给 RichTextLabel 添加标签,而不是直接使用 BBCode。

  • 在 RichTextLabel 中启用 Threading > Threaded (线程化) 属性。这并不会加快处理速度,但能防止主线程被阻塞,从而避免游戏运行过程中出现卡顿(掉帧)的现象。只有当你的项目确实需要时才开启线程化,因为使用多线程会带来一定的性能开销。

使用 push_[标签]() 和 pop() 函数代替 BBCode

如果你出于性能的考虑不想使用 BBCode,可以直接调用 RichTextLabel 提供的函数。这样就能在不直接在文本里写 BBCode 代码的情况下,实现同样的格式化效果。

每一个 BBCode 标签(包括各种特效)都对应一个 push_[tag]() 函数(其中 [tag] 就是该标签的名称)。此外还提供了一些便捷的函数,比如 push_bold_italics() ,它可以把 push_bold()push_italics() 合并成一个标签来使用。如果想查看完整的 push_[tag]() 函数列表,请参考: RichTextLabel class reference

pop() 函数用于结束 任何 标签。由于 BBCode 采用的是标签 堆栈 结构,因此使用 pop() 时,会优先关闭最近才开始(也就是最里层)的标签。

运行下面的脚本,将会得到与使用 BBCode [color=green]test [i]example[/i][/color] 完全相同的视觉效果:

extends RichTextLabel

func _ready():
    append_text("BBCode ")  # Trailing space separates words from each other.
    push_color(Color.GREEN)
    append_text("test ")  # Trailing space separates words from each other.
    push_italics()
    append_text("example")
    pop()  # Ends the tag opened by `push_italics()`.
    pop()  # Ends the tag opened by `push_color()`.

警告

“在使用格式化函数时,千万 不要 直接设置 text 属性。向 text 属性追加内容,将会抹除所有通过 append_text()push_[tag]()pop() 函数对 RichTextLabel 所做的修改。

参考

参见

部分 这些 BBCode 标签同样可以用在脚本变量 @export 的工具提示(tooltips)中,以及类参考(class reference)的 XML 源文件里。想了解更多信息,请查看: Class reference BBCode

标签

示例

b
{text} 使用 RichTextLabel 的粗体(或者粗斜体)字体。

[b]{text}[/b]

i
{text} 使用 RichTextLabel 的斜体(或者粗斜体)字体。

[i]{text}[/i]

u
{text} 上显示下划线。

[u]{text}[/u] [u color={color}]{text}[/u]

s
{text} 上显示删除线。

[s]{text}[/s] [s color={color}]{text}[/s]

code
{text} 使用 RichTextLabel 的等宽字体。

[code]{text}[/code]

char
将十六进制的 UTF-32 码位 {codepoint} 添加为 Unicode 字符。

[char={codepoint}]

p
{text} 添加为新的段落。支持配置选项,见 段落选项
[p]{text}[/p]
[p {options}]{text}[/p]
br
在文本中添加换行符,但不创建新段落。若在列表中使用,不会生成新的列表项,而是在当前项内插入换行。

[br]

hr
添加一条新的水平分割线(horizontal rule)来分隔内容。支持配置选项,详情请见 水平分隔线选项
[hr]
[hr {options}]
center
使得 {text} 水平居中。
等价于 [p align=center]

[center]{text}[/center]

left
使得 {text} 左对齐。
等价于 [p align=left]

[left]{text}[/left]

right
使得 {text} 右对齐。
等价于 [p align=right]

[right]{text}[/right]

fill
{text} 填满整个 RichTextLabel 的宽度。
等价于 [p align=fill]

[fill]{text}[/fill]

indent
单次缩进 {text}。缩进宽度与 [ul][ol] 中相同,但不创建列表点。

[indent]{text}[/indent]

url
创建一个超链接(带下划线且可点击的文本)。可以包含可选的 {text} 作为显示文字,或者直接原样显示 {link} 。支持配置选项,详情请见 URL 选项
必须配合 "meta_clicked" 信号来处理才能生效,处理 [url] 标签点击.
[url]{link}[/url]
[url={link}]{text}[/url]
[url {options}]{text}[/url]
hint
当鼠标悬停在文字上时,会显示一个提示框(Tooltip)。虽然不是强制要求的,但强烈建议使用双引号或单引号将提示文本括起来。需要注意的是,无法使用 \"\' 来转义引号。因此,如果你需要在提示文本中使用单引号(比如表示英文中的撇号或缩写),就必须使用双引号来包裹整个字符串。
[hint="{tooltip text displayed on hover}"]{text}[/hint]
img
插入位于 {路径} 的图像(可以是任意有效的 Texture2D 资源)。
如果提供了 {宽度},图像会尝试在保持纵横比的前提下适配该宽度。
如果同时提供了 {宽度}{高度},图像会缩放至该大小。
{宽度}{高度} 取值的末尾加上 % 可以指定控件宽高的百分比,而不是像素。
{width}{height} 的数值末尾添加 em,可将其指定为当前字体大小的倍数。例如,height=1em 会使图像的高度与周围文本的高度相同。
如果提供了 {垂直对齐} 配置,图像会尝试与周围的文本对齐,见 图像和表格的垂直对齐
支持配置选项,见 图像选项
[img]{路径}[/img]
[img={宽度}]{路径}[/img]
[img=<宽度>x<高度>]{路径}[/img]
[img={垂直对齐}]{路径}[/img]
[img {选项}]{路径}[/img]
font
{text} 使用位于 {路径} 的字体资源。
支持配置选项,见 字体选项
[font={路径}]{文本}[/font]
[font {选项}]{文本}[/font]
font_size
{text} 使用自定义字体大小。

[font_size={大小}]{文本}[/font_size]

dropcap
{text} 使用不同的字号和颜色;如果内容足够长,标签内的文字会自动跨行(换行)显示。
首字下沉( drop cap )通常只包含一个大写字母,但 [dropcap] 标签支持包含多个字符。 margins (外边距)的数值需要用逗号分隔,可以是正数、零或负数。数值之间绝对 不能 用空格隔开,否则这些数值将无法被正确解析。将顶部和底部的外边距设置为负数会特别有用,因为这可以让段落中的其他文字显示在首字下沉字符的下方(实现更紧凑的环绕效果)。

[dropcap font={font} font_size={size} color={color} outline_size={size} outline_color={color} margins={left},{top},{right},{bottom}]{text}[/dropcap]

opentype_features
{text} 启用自定义的 OpenType 字体特性。这些特性必须提供为一个以逗号分隔的 {list} (列表)。数值之间绝对 不能 用空格隔开,否则列表将无法被正确解析。
[opentype_features={list}]
{text}
[/opentype_features]
lang
覆盖 RichTextLabelBiDi > Language 属性所设置的 {text} 语言。 {code} 必须是一个 ISO language code 。这可以在不另起新段落的情况下,强制对某段文字使用特定的书写系统(script)。某些字体文件可能包含针对特定书写系统的替换字形,在这种情况下,它们将会被调用。

[lang={code}]{text}[/lang]

color
修改 {text} 的颜色。设置的颜色必须使用通用名称(见 具名颜色)或十六进制格式(例如 #ff00ff,见 十六进制颜色代码)。

[color={code/name}]{text}[/color]

bgcolor
{text} 的后方绘制颜色。这可以用来高亮显示文本。它接受与 color 标签相同的参数值。默认情况下,颜色块会带有一点内边距(padding),这个间距由 RichTextLabel 节点中的 text_highlight_h_padding (水平内边距)和 text_highlight_v_padding (垂直内边距)这两个主题属性来控制。如果将内边距设置为 0 ,可以避免当相邻的行或列也存在背景色时,可能出现的重叠问题。

[bgcolor={code/name}]{text}[/bgcolor]

fgcolor
{text} 的前方绘制颜色。这可以用来通过设置不透明的前景色来‘涂黑/遮盖’文本。它接受与 color 标签相同的参数值。默认情况下,会带有一点内边距(padding),这个间距由 RichTextLabel 节点中的 text_highlight_h_padding (水平内边距)和 text_highlight_v_padding (垂直内边距)这两个主题属性来控制。如果将内边距设置为 0 ,可以避免在相邻的行或列存在前景色时可能出现的重叠问题。

[fgcolor={code/name}]{text}[/fgcolor]

outline_size
{text} 使用自定义字体轮廓大小。
[outline_size={size}]
{text}
[/outline_size]
outline_color
{text} 使用自定义轮廓颜色。接受的值和 color 标签一致。
[outline_color={code/name}]
{text}
[/outline_color]
table
创建列数为 {number} 的表格。定义表格中的单元格请使用 cell 标签。
如果提供了 {valign} (垂直对齐)配置,表格会尝试与周围的文本进行对齐,详情请见 图像和表格的垂直对齐
如果使用了基线对齐,表格会按照索引为 {alignment_row} (从 0 开始计数)的那一行的基线来进行对齐。
{name} 是给辅助应用(例如屏幕阅读器)使用的表格名称。
[table={number}]{cells}[/table]
[table={number},{valign}]{cells}[/table]
[table={number},{valign},{alignment_row}]{cells}[/table]
[table={number},{valign},{alignment_row} name={name}]{cells}[/table]
cell
向表格中添加一个文本为 {text} 的单元格。
如果提供了 {ratio} ,该单元格会尝试按照比例进行扩展,以匹配该值,同时也会参考其他单元格及其比例值。
支持配置选项,详情请见: 单元格选项
[cell]{text}[/cell]
[cell={ratio}]{text}[/cell]
[cell {options}]{text}[/cell]
ul
添加无序列表。列表项 {item} 必须以一行一个的形式提供。
项目符号可以使用 {bullet} 参数自定义,见 无序列表项目符号
[ul]{items}[/ul]
[ul bullet={bullet}]{items}[/ul]
ol
添加有序(编号)列表,类型由 {type} 给定(见 有序列表类型)。列表项 {items} 必须以一行一个的形式提供。

[ol type={type}]{items}[/ol]

lbrb
分别添加 []。用于转义 BBCode 标记。
这些是自闭合标签,不需要手动关闭(不存在 [/lb][/rb] 这种关闭标签)。
[lb]b[rb]text[lb]/b[rb] 会被显示为 [b]text[/b]
部分 Unicode 控制字符可以使用对应的自闭合标签添加。
相比于直接在文本中粘贴这些控制字符,
这种方法更方便维护。
[lrm] (左到右标记)、 [rlm] (右到左标记)、 [lre] (左到右嵌入)、
[rle] (从右到左嵌入), [lro] (从左到右覆盖), [rlo] (从右到左覆盖),
[pdf] (弹出方向格式), [alm] (阿拉伯字母标记), [lri] (从左到右隔离),
[rli] (从右向左隔离符), [fsi] (首个强字符隔离符), [pdi] (弹出方向隔离符),
[zwj] (零宽连接符), [zwnj] (零宽非连接符), [wj] (词连接符),
[shy] (软连字符)

备注

如果想要让粗体( [b] )和斜体( [i] )标签达到最好的显示效果,最好在 RichTextLabel 节点的主题覆盖(theme overrides)中设置好对应的自定义字体。如果没有定义专门的粗体或斜体字体,Godot 就会自动生成 faux bold and italic fonts 。和专门手工设计的粗体/斜体字体变体相比,这些自动生成的字体效果通常都不太好看。

等宽( [code] )标签 只有 在 RichTextLabel 节点的主题覆盖(theme overrides)中设置了自定义字体时才会生效。否则,等宽文本将直接使用普通的常规字体。

目前还没有用于控制文本垂直居中的BBCode标签.

所有标签(tags)都可以跳过这些选项。

段落选项

  • align

    left (or l), center (or c), right (or r), fill (or f)

    默认

    left

    文本水平对齐。

  • bidi_overridest

    default (of d), uri (or u), file (or f), email (or e), list (or l), none (or n), custom (or c)

    默认

    default

    结构化文本覆盖。

  • justification_flagsjst

    以逗号分隔的下列值列表(每个逗号后面不要加空格): kashida (或 k )、 word (或 w )、 trim (或 tr )、 after_last_tab (或 lt )、 skip_last (或 sl )、 skip_last_with_chars (或 sv )、 do_not_skip_single (或 ns )。

    默认

    word,kashida,skip_last,do_not_skip_single

    两端对齐(填充对齐)选项。详见 TextServer

  • directiondir

    ltr (或 l), rtl (或 r), auto (或 a)

    默认

    继承

    基础双向(BiDi)文本方向。

  • languagelang

    ISO 语言代码。见 区域设置代码

    默认

    继承

    区域设置覆盖。有些字体文件可能包含针对特定书写系统(script)的替代字形,如果包含的话,这些字形将会被使用。

  • tab_stops

    浮点数列表,例如 10.0,30.0

    默认

    字体中空格字符的宽度

    覆盖每个制表符(Tab)字符的水平偏移量。当到达列表末尾时,制表符的停靠位置会循环重复。例如,如果你将 tab_stops 设置为 10.0,30.0 ,那么从 RichTextLabel 的起始位置算起,第一个制表符会停在 10 像素处,第二个制表符会停在 10 + 30 = 40 像素处,而第三个制表符会停在 10 + 30 + 10 = 50 像素处。

处理 [url] 标签点击

默认情况下,[url] 标签在单击时不执行任何操作.这是为了允许灵活使用 [url] 标签,而不是限制它们在Web浏览器中打开URL.

要处理被点击的 [url] 标签,需要将 RichTextLabel 节点的 meta_clicked 信号连接到一个脚本函数上。

例如,可以将以下方法连接到 meta_clicked 信号,从而使用用户默认的网页浏览器来打开被点击的链接(URL):

# This assumes RichTextLabel's `meta_clicked` signal was connected to
# the function below using the signal connection dialog.
func _richtextlabel_on_meta_clicked(meta):
    # `meta` is not guaranteed to be a String, so convert it to a String
    # to avoid script errors at runtime.
    OS.shell_open(str(meta))

对于更高级的用例,也可以将 JSON 数据存储在 [url] 标签的选项(option)里,然后在处理 meta_clicked 信号的函数中对其进行解析。例如:

[url={"example": "value"}]JSON[/url]

水平分隔线选项

  • color

    颜色名称或十六进制格式的颜色

    默认

    Color(1, 1, 1, 1)

    分隔线的颜色色调(调制)。

  • height

    整数

    默认

    2

    分隔线的目标高度(以像素为单位)。如果在数值的末尾加上 % ,就可以将其指定为控件宽度的百分比,而不是像素。

  • width

    整数

    默认

    90%

    分隔线的目标宽度(以像素为单位)。如果在数值的末尾加上 % ,就可以将其指定为控件宽度的百分比,而不是像素。

  • align

    left (或 l), center (或 c), right (或 r)

    默认

    left

    水平对齐。

URL 选项

  • underline

    always, never, hover

    默认

    always

    URL 下划线模式。

  • tooltip

    字符串。

    默认

    URL 工具提示。

  • href

    字符串。

    默认

    URL 目标地址。

图像选项

  • color

    颜色名称或十六进制格式的颜色

    默认

    继承

    图像的着色颜色(调制)。

  • height

    浮点数

    默认

    继承

    图像的目标高度,单位是像素。

    也可以指定像素以外的其他单位:

    • 在值的末尾添加 %,将其指定为控件宽度的百分比,而不是像素。例如,height=50% 会使图像的高度变为控件宽度的一半。

    • 在数值的末尾加上 em ,就可以把它指定为相对于周围字体大小的比例,而不是固定的像素。举个例子,如果你设置 height=1em ,那么这张图片的高度就会变得和周围的文字一模一样高。

  • width

    浮点数

    默认

    继承

    图像的目标宽度(以像素为单位)。

    也可以指定像素以外的其他单位:

    • 在值的末尾添加 %,将其指定为控件宽度的百分比,而不是像素。例如,width=50% 会使图像占据控件宽度的一半。

    • 在数值的末尾加上 em ,就可以把它指定为相对于周围字体大小的比例,而不是固定的像素。举个例子,如果你设置 width=1em ,那么这张图片的宽度就会变得和周围文字的高度一模一样。

  • region

    x,y,width,height(单位:像素)

    默认

    继承

    图像的区域框。可用于显示精灵表中的单个图像。

  • pad

    falsetrue

    默认

    false

    如果设为 true 且图像小于 widthheight 指定的大小,那么就会为图像加上边距让大小一致,不会进行缩放。

  • tooltip

    字符串

    默认

    图像的工具提示。

  • align

    图像和表格的垂直对齐

    默认

    center,center

    图片与周围文本的对齐方式。

  • alt

    字符串

    默认

    供辅助应用(屏幕阅读器)使用的图片描述。

图像和表格的垂直对齐

当在 [img][table] 标签中提供垂直对齐值时,图片/表格会尝试根据周围的文本进行对齐。这种对齐是通过结合图片上的一个垂直点和文本上的一个垂直点来实现的。图片上有 3 个可选的点( top 顶部、 center 居中、 bottom 底部),而文本和表格上有 4 个可选的点( top 顶部、 center 居中、 baseline 基线、 bottom 底部),你可以将它们进行任意组合使用。

如果要同时指定两个点,请将它们的全称或简写作为图片或表格标签的值来使用:

text [img=top,bottom]...[/img] text
text [img=center,center]...[/img] text
../../_images/bbcode_in_richtextlabel_image_align.webp
text [table=3,center]...[/table] text  # Center to center.
text [table=3,top,bottom]...[/table] text # Top of the table to the bottom of text.
text [table=3,baseline,baseline,1]...[/table] text # Baseline of the second row (rows use zero-based indexing) to the baseline of text.
../../_images/bbcode_in_richtextlabel_table_align.webp

你也可以只指定一个值( topcenterbottom ),这样就会自动使用对应的预设值(分别对应 top-topcenter-centerbottom-bottom )。

这些值的简写分别是 ttop )、 ccenter )、 lbaseline )和 bbottom )。

字体选项

  • namen

    有效的 Font 资源路径。

    默认

    继承

    字体资源路径。

  • sizes

    数字,单位为像素。

    默认

    继承

    自定义字体大小。

  • glyph_spacinggl

    数字,单位为像素。

    默认

    继承

    每个字形的额外间距。

  • space_spacing, sp

    数字,单位为像素。

    默认

    继承

    空格字符的额外间距。

  • top_spacingtop

    数字,单位为像素。

    默认

    继承

    行上方的额外间距。

  • bottom_spacingbt

    数字,单位为像素。

    默认

    继承

    行下方的额外间距。

  • emboldenemb

    浮点数字。

    默认

    0.0

    字体加粗强度,非零时会加粗字体的轮廓。负值会降低轮廓的粗细。

  • face_indexfi

    整数。

    默认

    0

    TrueType / OpenType 合集中活动字体的索引号。

  • slantsln

    浮点数字。

    默认

    0.0

    字体倾斜强度,正值会将字形向右倾斜,负值会将字形向左倾斜。

  • opentype_variationotv

    用逗号分隔的 OpenType 可变字体标签列表(每个逗号后面不要加空格)。

    默认

    字体的 OpenType 变体坐标。见 OpenType 变体标签

    注意:取值应使用 " 包裹,这样就能够在其中使用 =

[font otv="wght=200,wdth=400"] # Sets variable font weight and width.
  • opentype_featuresotf

    用逗号分隔的 OpenType 特性标签列表(每个逗号后面不要加空格)。

    默认

    字体的 OpenType 特性。见 OpenType 特性标签

    注意:取值应使用 " 包裹,这样就能够在其中使用 =

[font otf="calt=0,zero=1"] # Disable contextual alternates, enable slashed zero.

具名颜色

对于那些允许通过名称来指定颜色的标签,你可以直接使用内置 Color 类中的常量名称。这些颜色名称支持多种不同的大小写风格:比如 DARK_REDDarkReddarkred ,最终呈现的效果都是完全一样的。

关于颜色常量的列表,请查看这张图片:

../../_images/color_constants.png

查看完整尺寸

十六进制颜色代码

对于不透明的 RGB 颜色,支持任何有效的 6 位十六进制代码,例如 [color=#ffffff]white[/color] 。同时也支持简写的 RGB 颜色代码,比如 #6f2 (它等同于 #66ff22 )。

对于带透明度的 RGB 颜色,可以使用任何 8 位的 RGBA 十六进制代码,例如 [color=#ffffff88]translucent white[/color] 。需要注意的是,Alpha 通道(即透明度)是颜色代码的 最后 一部分,而不是第一部分。此外,也支持简写的 RGBA 颜色代码,比如 #6f28 (等同于 #66ff2288 )。

单元格选项

  • shrink

    falsetrue

    默认

    true

    如果为 true ,单元格可以根据其内容自动收缩。

  • expand

    整数

    默认

    1

    单元格扩张比例。定义的是哪些单元格会尝试按比例扩展到其他单元格,以及相应的扩张比例。

  • border

    颜色名称或十六进制格式的颜色

    默认

    继承

    单元格边框颜色。

  • bg

    颜色名称或十六进制格式的颜色

    默认

    继承

    单元格背景色。如果想要单双行使用不同的背景色,请使用 bg=单行颜色,双行颜色

  • padding

    4个用逗号分隔的浮点数(每个逗号后面不要加空格)

    默认

    0,0,0,0

    单元格左侧、上方、右侧、下方的内边距。

无序列表项目符号

默认情况下, [ul] 标签会使用 Unicode 字符 U+2022 (即 "Bullet" 实心圆点)作为列表的项目符号。这个表现和网页浏览器里的默认效果非常相似。你可以通过 [ul bullet={bullet}] 的格式来自定义项目符号。如果提供了这个 {bullet} 参数,它必须是一个没有加引号的字符串(例如 [bullet=*] )。你还可以在项目符号后面加上空格,来增加符号和列表文字之间的间距。

关于可以直接复制并粘贴到 bullet 参数中的常用项目符号列表,请参阅维基百科上的 项目符号(排版) <https://en.wikipedia.org/wiki/Bullet_(typography)>__ 页面。

有序列表类型

有序列表可以使用数字或字母自动升序标记条目。该标签支持以下类型选项:

  • 1 - 数字,会尽量使用语言对应的数字系统。

  • aA - 小写和大写拉丁字母。

  • iI - 小写和大写罗马数字。

文本效果

BBCode 还可以用来创建各种不同的文字特效,并且你可以选择是否让这些特效带有动画。Godot 引擎开箱即用地提供了好几种可以自定义的特效,而且你也可以非常轻松地创建属于你自己的特效。默认情况下, when the SceneTree is paused ,带有动画的特效也会跟着暂停。你可以通过调整 RichTextLabel 节点的 Process > Mode (处理 > 模式) 属性来改变这一行为。

下面所有的示例中,列出的标签格式里提到的选项值均为默认值。

备注

那些会移动字符位置的文字特效,可能会导致字符被 RichTextLabel 节点的边界给‘截断’(也就是显示不全)。

你可以通过以下两种方法来解决这个问题:在选中 RichTextLabel 节点后,在检查器(Inspector)中关闭 Control > Layout > Clip Contents (裁剪内容) 选项;或者,在使用该特效的那一行文字的上方和下方添加换行符,确保文字周围留有足够的边距。

脉冲

../../_images/bbcode_in_richtextlabel_effect_pulse.webp

Pulse(脉冲)特效能创建一个动态的脉冲效果,它会同时改变(乘算)每个字符的透明度和颜色。这个特效非常适合用来突出显示某些特定的文本。它的标签格式为 [pulse freq=1.0 color=#ffffff40 ease=-2.0]{text}[/pulse]

freq 控制半脉冲循环的频率(数值越大,闪烁越快)。一个完整的脉冲循环需要 2 * (1.0 / freq) 秒。 color 是闪烁时的目标颜色乘数。默认值会让文字大部分淡出,但不会完全消失。 ease 是要使用的缓动函数指数。负数会提供 in-out(进出)缓动效果,这也是为什么默认值设为 -2.0 的原因。

波浪

../../_images/bbcode_in_richtextlabel_effect_wave.webp

Wave(波浪)特效能让文字上下起伏移动。它的标签格式为 [wave amp=50.0 freq=5.0 connected=1]{text}[/wave]

amp 控制特效的高低幅度(也就是波浪起伏的大小),而 freq 则控制文字上下波动的速度。如果 freq 设为 0 ,将不会产生可见的波浪;如果 freq 设为负数,同样也不会显示波浪。如果 connected 设为 1 (默认值),带有连字(ligatures)的字形会被当作一个整体一起移动。如果 connected 设为 0 ,即使字形之间通过连字连在一起,每个字形也会被单独移动。这可以用来规避某些字体连字导致的渲染问题。

旋风

../../_images/bbcode_in_richtextlabel_effect_tornado.webp

Tornado(龙卷风)特效会让文字绕着圈移动。它的标签格式为 [tornado radius=10.0 freq=1.0 connected=1]{text}[/tornado]

radius 是控制文字偏移范围的圆形半径(也就是文字绕圈的大小), freq 则决定了文字绕圈移动的速度。如果 freq 设为 0 ,动画会暂停;如果 freq 设为负数,动画则会倒着播放。如果 connected 设为 1 (默认值),带有连字(ligatures)的字形会被当作一个整体一起移动。如果 connected 设为 0 ,即使字形之间通过连字连在一起,每个字形也会被单独移动。这可以用来规避某些字体连字导致的渲染问题。

抖动

../../_images/bbcode_in_richtextlabel_effect_shake.webp

Shake(抖动)特效能让文字产生抖动的效果。它的标签格式为 [shake rate=20.0 level=5 connected=1]{text}[/shake]

rate 控制文字抖动的速度, level 控制文字偏离原始位置的距离(也就是抖动的幅度)。如果 connected 设为 1 (默认值),带有连字(ligatures)的字形会被当作一个整体一起移动。如果 connected 设为 0 ,即使字形之间通过连字连在一起,每个字形也会被单独移动。这可以用来规避某些字体连字导致的渲染问题。

渐隐

../../_images/bbcode_in_richtextlabel_effect_fade.webp

Fade(淡出)特效会创建一个静态的淡出效果,它会直接对每个字符的透明度(不透明度)进行乘法混合。它的标签格式为 [fade start=4 length=14]{text}[/fade]

start 控制衰减(淡出)的起始位置,它是相对于你插入 fade 命令的位置来计算的; length 则控制淡出效果要跨越多少个字符来完成。

彩虹

../../_images/bbcode_in_richtextlabel_effect_rainbow.webp

Rainbow(彩虹)特效能让文字呈现出随时间变化的彩虹色。它的标签格式为 [rainbow freq=1.0 sat=0.8 val=0.8 speed=1.0]{text}[/rainbow]

freq 决定了彩虹颜色在重复之前会跨越多少个字(也就是彩虹周期的长度), sat 代表彩虹的饱和度, val 代表彩虹的明度。 speed 则是每秒钟彩虹完整循环的次数。如果 speed 是正数,动画会正向播放;如果设为 0 ,动画就会暂停;如果 speed 是负数,动画则会倒着播放。

字体描边(Font outlines) 不会 受到彩虹特效的影响(它们会保持原本的颜色)。而现有的字体颜色则会被彩虹特效直接覆盖。不过,CanvasItem 的 Modulate (调制)和 Self Modulate (自调制)属性依然会影响彩虹特效的最终视觉效果,因为调制操作会将这些属性与特效的最终颜色进行相乘混合。

自定义 BBCode 标签和文本效果

可以通过扩展 RichTextEffect 资源类型来创建自己的 BBCode 标签。首先扩展 RichTextEffect 资源类型并为脚本提供 class_name,这样就能够在检查器中选择该效果。如果想在编辑器中运行这些自定义效果,请在 GDScript 文件中添加 @tool 注解。RichTextLabel 不需要附加脚本,也不需要在 tool 模式下运行。注册效果的方法是将这个新建的效果在检查器中加入到 Markup > Custom Effects 数组中,或者在代码中使用 install_effect() 方法:

在保存了一个带有 ``class_name`` 且继承自 RichTextEffect 的脚本之后,去选择一个自定义的 RichTextEffect

在保存了一个带有 class_name 且继承自 RichTextEffect 的脚本之后,去选择一个自定义的 RichTextEffect

警告

“如果自定义特效没有在 RichTextLabel 的 Markup > Custom Effects 属性中进行注册,那么该特效将不会显示,并且原始的标签会保持原样(直接作为普通文本显示出来)。

你只需要重写(extend)一个函数: _process_custom_fx(char_fx) 。另外,你还可以选择性地添加一个名为 bbcode 的成员变量,来提供一个自定义的 BBCode 标识符。代码会自动检查 bbcode 这个属性;如果你没设置它,程序就会直接使用该脚本的文件名,来自动确定对应的 BBCode 标签是什么。

_process_custom_fx

这里就是每个特效具体逻辑发挥作用的地方。在文字渲染的绘制阶段,它会为每一个字形(glyph)被调用一次。它会传入一个 CharFXTransform 对象,这个对象包含了一些变量,用来控制相关联的字形具体该如何被渲染:

  • 如果当前特效是在绘制文字描边时被调用的,那么 outline 的值就为 true

  • range 会以索引(index)的形式,告诉你当前正处于某个自定义特效块中的第几个位置。

  • elapsed_time 是文本效果运行的总时间.

  • visible 会告诉你当前字形是否可见,同时也允许你隐藏指定的文本部分。

  • offset 是相对于该字形在正常情况下本应渲染的位置,所产生的偏移量。

  • color 是指定字形(glyph)的颜色。

  • glyph_indexfont 分别代表正在被绘制的字符(字形)索引,以及用来绘制它的字体数据资源。

  • 最后, env 是一个 Dictionary (字典),里面存放着分配给某个自定义特效的参数。你可以使用 get() 方法(并带上一个可选的默认值)来提取每一个参数——前提是用户确实指定了它。举个例子,如果你写了 [custom_fx spread=0.5 color=#FFFF00]test[/custom_fx] ,那么它的 env 字典里就会包含一个浮点型的 spread 参数和一个 Color 类型的 color 参数。具体的更多使用示例,可以接着往下看哦。

关于这个函数,最后一点需要注意的就是需要返回布尔值 true 来确认效果已正确处理完毕。这样一来,如果在渲染某个字形时遇到了问题,就会跳出自定义效果的渲染,直到用户修正了自定义效果逻辑中所发生的错误。

以下是一些自定义效果的示例:

幽灵

@tool
extends RichTextEffect
class_name RichTextGhost

# Syntax: [ghost freq=5.0 span=10.0][/ghost]

# Define the tag name.
var bbcode = "ghost"

func _process_custom_fx(char_fx):
    # Get parameters, or use the provided default value if missing.
    var speed = char_fx.env.get("freq", 5.0)
    var span = char_fx.env.get("span", 10.0)

    var alpha = sin(char_fx.elapsed_time * speed + (char_fx.range.x / span)) * 0.5 + 0.5
    char_fx.color.a = alpha
    return true

矩阵

@tool
extends RichTextEffect
class_name RichTextMatrix

# Syntax: [matrix clean=2.0 dirty=1.0 span=50][/matrix]

# Define the tag name.
var bbcode = "matrix"

# Gets TextServer for retrieving font information.
func get_text_server():
    return TextServerManager.get_primary_interface()

func _process_custom_fx(char_fx):
    # Get parameters, or use the provided default value if missing.
    var clear_time = char_fx.env.get("clean", 2.0)
    var dirty_time = char_fx.env.get("dirty", 1.0)
    var text_span = char_fx.env.get("span", 50)

    var value = get_text_server().font_get_char_from_glyph_index(char_fx.font, 1, char_fx.glyph_index)

    var matrix_time = fmod(char_fx.elapsed_time + (char_fx.range.x / float(text_span)), \
                           clear_time + dirty_time)

    matrix_time = 0.0 if matrix_time < clear_time else \
                  (matrix_time - clear_time) / dirty_time

    if matrix_time > 0.0:
        value = int(1 * matrix_time * (126 - 65))
        value %= (126 - 65)
        value += 65
    char_fx.glyph_index = get_text_server().font_get_glyph_index(char_fx.font, 1, value, 0)
    return true

这将增加一些新的BBCode命令, 可以像这样使用:

[center][ghost]This is a custom [matrix]effect[/matrix][/ghost] made in
[pulse freq=5.0 height=2.0][pulse color=#00FFAA freq=2.0]GDScript[/pulse][/pulse].[/center]