RichTextLabel 中的 BBCode

前言

Label 节点非常适合显示基本文本,但它们有局限性。如果更改文本的颜色或对齐方式,则该更改会影响标签节点中的所有文本。没法只让一部分文本用一种颜色,或者只居中一部分文本。要绕过此限制,可以使用 RichTextLabel

RichTextLabel 允许在一个控件中显示复杂的文本标记。它内置用来生成标记的 API,同时也可以对 BBCode 进行解析。

大部分BBCode标签也可以用在 XML 格式的类参考文档 .

使用 BBCode

你可以把格式统一的文本写在“Text”属性里,但如果想用 BBCode 标记,你就应该换成使用“Bb Code”部分的“Text”属性( bbcode_text )。写入这个属性将触发对你的标记的解析,从而按要求对文本进行格式化。在这之前,你需要打开“Bb Code”部分的“Enabled”复选框( bbcode_enabled )。

../../_images/bbcodeText.png

例如, BBCode [color=blue]blue[/color] 将会出现蓝色的单词“blue”。

../../_images/bbcodeDemo.png

填写完 BBCode 的“Text”属性后,你可以看到普通的“Text”属性变成了不带 BBCode 的版本。这个文本属性会随 BBCode 属性更新,但你不能去编辑,否则就会丢失 BBCode 标记。所有修改都必须在 BBCode 参数里完成。

备注

要使用 [b] (粗体), [i] (斜体)或 [code] 等BBCode标签, 必须先为RichTextLabel节点设置对应的自定义字体(位于Custom Fonts下).

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

参考

命令

标签

描述

加粗

[b]{text}[/b]

使得 {text} 呈现粗体.

斜体

[i]{text}[/i]

使得 {text} 呈现斜体.

下划线

[u]{text}[/u]

使得 {text} 呈现下划线.

删除线

[s]{text}[/s]

在 {text} 上显示删除线。

代码

[code]{text}[/code]

使得 {text} 使用代码字体(通常为等宽字体)。

居中

[center]{text}[/center]

使得 {text} 水平居中.

右对齐

[right]{text}[/right]

使得 {text} 右对齐.

填充

[fill]{text}[/fill]

使{text}填充RichTextLabel的宽度.

缩进

[indent]{text}[/indent]

增加 {text} 的缩进级别.

URL

[url]{url}[/url]

显示 {url},文字带有下划线并且可以点击。必须在“meta_clicked”信号中处理,点击才会生效。参阅 处理 [url] 标签点击

URL(引用)

[url=<url>]{text}[/url]

使 {text} 引用 <url>(下划线并可点击)。必须在“meta_clicked”信号中处理,点击才会生效。参阅 处理 [url] 标签点击

图片

[img]{path}[/img]

插入由资源路径 {path} 所指示的图片.

调整大小后的图片

[img=<width>]{path}[/img]

插入由资源路径 {path} 所指示的图片, 并指定其宽度(保持宽高比).

调整大小后的图片

[img=<width>x<height>]{path}[/img]

插入由资源路径 {path} 所指示的图片, 指定其宽与高.

字体

[font=<path>]{text}[/font]

为 {text} 内容设置自定义字体, 字体由 <path> 指定.

颜色

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

改变 {text} 的颜色, 可以使用颜色名称或十六进制码指定颜色, 如 #ff00ff .

表格

[table=<number>]{cells}[/table]

创建一个包含 <number>列数的表.

单元格

[cell]{text}[/cell]

将带有{text}的单元格添加到表格中.

内置的颜色名称

以下列出 [color=<name>] 标签所支持的有效颜色名称:

  • aqua

  • black

  • blue

  • fuchsia

  • gray

  • green

  • lime

  • maroon

  • navy

  • purple

  • red

  • silver

  • teal

  • white

  • yellow

十六进制颜色代码

不透明的 RGB 颜色支持使用任何有效的 6 位十六进制数,例如 [color=#ffffff]白色[/color]。也支持短的 RGB 颜色码,比如 #6f2(等价于 #66ff22)。

透明的 RGB 颜色可以使用任意 8 位十六进制数,例如 [color=#88ffffff]半透明白色[/color]。请注意这里的 alpha 通道是颜色码中的第一个分量,不是最后一个。也支持短的 RGBA 颜色码,比如 #86f2(等价于 #8866ff22)。

处理 [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 run-time.
    OS.shell_open(str(meta))

要支持更高级的用法,也可以在 [url] 标签的选项中保存 JSON,然后在处理 meta_clicked 信号的函数中解析。例如:[url={"example": "value"}]JSON[/url]

图像垂直偏移

您可以对图像使用自定义字体,以便将其垂直对齐。

  1. 创建 BitmapFont 字体资源

  2. 将这个位图字体的 ascent 属性设置为正值,即你的高度偏移量

  3. 按下面方式设置 BBCode 标签:[font=<字体路径>][img]{图像路径}[/img][/font]

动画特效

BBCode也可以用来创建不同的文字动画特效. 内置了五种特效, 当然你也可以轻松创建出自已的特效.

波浪

../../_images/wave.png

波浪会使文字上下波动。其标签格式是 [wave amp=50 freq=2][/wave]amp 控制特效高低,freq 控制文字上下移动的速度。

旋风

../../_images/tornado.png

龙卷风使文字在圆圈内移动, 它的标签格式是 [tornado radius=5 freq=2][/tornado] . radius 是控制偏移的圆半径, freq 是文字在圆中移动的速度.

抖动

../../_images/shake.png

抖动使文字摇动, 它的标签格式是 [shake rate=5 level=10][/shake] . rate 控制文本抖动的速度, level 控制文本与原点的偏移程度.

渐隐

../../_images/fade.png

渐变在没有动画的文本上创建一个渐变效果, 它的标签格式是 [fade start=4 length=14][/fade] . start 控制相对于插值淡入命令的起始位置, length 控制淡出应该发生多少个字符.

彩虹

../../_images/rainbow.png

彩虹让文字呈现出随时间变化的彩虹色, 它的标签格式是 [rainbow freq=0.2 sat=10 val=20][/rainbow] . freq 是每秒完整的彩虹周期数, sat 是彩虹的饱和度, val 是彩虹的数值.

自定义 BBCode 标签和文本效果

可以通过扩展 RichTextEffect 资源类型来创建自己的 BBCode 标签。首先扩展 RichTextEffect 资源类型,如果想在编辑器中运行这些自定义效果,请在 GDScript 文件中添加 tool 前缀。RichTextLabel 不需要附加脚本,也不需要在 tool 模式下运行。新建的特效可以使用检查器中的 Custom Effects 属性启用。

警告

If the custom effect is not registered within the RichTextLabel's Custom Effects property, no effect will be visible and the original tag will be left as-is.

只需要扩展一个函数: _process_custom_fx(char_fx) , 或者可以通过添加成员名称 bbcode 来提供自定义BBCode标识符, 该代码将自动检查bbcode属性, 或使用文件名来决定BBCode标签应该是什么.

_process_custom_fx

这是每个效果的逻辑生效的地方, 在文本渲染绘制阶段, 每个字符被调用一次, 将传入一个 CharFXTransform 对象, 该对象拥有一些变量来控制相关字符的渲染方式:

  • identity身份 指定正在处理哪个自定义效果, 应该用它来控制代码流程.

  • relative_index 告诉你在一个给定的自定义效果区块中的索引有多远.

  • absolute_index 告诉你作为索引到整个文本的距离.

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

  • visible 将告诉你这个字符是否可见, 也允许你隐藏文本的某个部分.

  • offset 是相对于给定字符在正常情况下应该呈现的位置的偏移位置.

  • color 是一种预先规定的字符颜色.

  • 最后, env 是一个指定自定义效果的参数 Dictionary . 如果用户指定, 您可以使用 Get() 和可选默认值来检索每个参数. 例如, [custom_fx spread=0.5 color=#FFFF00]test[/custom_fx] 在其 env 字典中将有一个浮动 spread 和颜色 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.absolute_index / span)) * 0.5 + 0.5
    char_fx.color.a = alpha
    return true

脉冲

tool
extends RichTextEffect
class_name RichTextPulse

# Syntax: [pulse color=#00FFAA height=0.0 freq=2.0][/pulse]

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

func _process_custom_fx(char_fx):
    # Get parameters, or use the provided default value if missing.
    var color = char_fx.env.get("color", char_fx.color)
    var height = char_fx.env.get("height", 0.0)
    var freq = char_fx.env.get("freq", 2.0)

    var sined_time = (sin(char_fx.elapsed_time * freq) + 1.0) / 2.0
    var y_off = sined_time * height
    color.a = 1.0
    char_fx.color = char_fx.color.linear_interpolate(color, sined_time)
    char_fx.offset = Vector2(0, -1) * y_off
    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"

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 = char_fx.character

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

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

    if value >= 65 && value < 126 && matrix_time > 0.0:
        value -= 65
        value = value + int(1 * matrix_time * (126 - 65))
        value %= (126 - 65)
        value += 65
    char_fx.character = value
    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]