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:

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

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

图像垂直偏移

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

  1. 创建 BitmapFont 字体资源

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

  3. 按下面方式设置BBCode标签:[font=<font-path>][img]{image-path}[/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 属性启用。

只需要扩展一个函数: _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 , 以验证结果处理正确, 这样一来, 如果这个预先规定的字符渲染出现问题, 它将完全退出自定义渲染的效果, 直到用户修复自定义渲染出现的任何错误.

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

幽灵

  1. tool
  2. extends RichTextEffect
  3. class_name RichTextGhost
  4. # Syntax: [ghost freq=5.0 span=10.0][/ghost]
  5. # Define the tag name.
  6. var bbcode = "ghost"
  7. func _process_custom_fx(char_fx):
  8. # Get parameters, or use the provided default value if missing.
  9. var speed = char_fx.env.get("freq", 5.0)
  10. var span = char_fx.env.get("span", 10.0)
  11. var alpha = sin(char_fx.elapsed_time * speed + (char_fx.absolute_index / span)) * 0.5 + 0.5
  12. char_fx.color.a = alpha
  13. return true

脉冲

  1. tool
  2. extends RichTextEffect
  3. class_name RichTextPulse
  4. # Syntax: [pulse color=#00FFAA height=0.0 freq=2.0][/pulse]
  5. # Define the tag name.
  6. var bbcode = "pulse"
  7. func _process_custom_fx(char_fx):
  8. # Get parameters, or use the provided default value if missing.
  9. var color = char_fx.env.get("color", char_fx.color)
  10. var height = char_fx.env.get("height", 0.0)
  11. var freq = char_fx.env.get("freq", 2.0)
  12. var sined_time = (sin(char_fx.elapsed_time * freq) + 1.0) / 2.0
  13. var y_off = sined_time * height
  14. color.a = 1.0
  15. char_fx.color = char_fx.color.linear_interpolate(color, sined_time)
  16. char_fx.offset = Vector2(0, -1) * y_off
  17. return true

矩阵

  1. tool
  2. extends RichTextEffect
  3. class_name RichTextMatrix
  4. # Syntax: [matrix clean=2.0 dirty=1.0 span=50][/matrix]
  5. # Define the tag name.
  6. var bbcode = "matrix"
  7. func _process_custom_fx(char_fx):
  8. # Get parameters, or use the provided default value if missing.
  9. var clear_time = char_fx.env.get("clean", 2.0)
  10. var dirty_time = char_fx.env.get("dirty", 1.0)
  11. var text_span = char_fx.env.get("span", 50)
  12. var value = char_fx.character
  13. var matrix_time = fmod(char_fx.elapsed_time + (char_fx.absolute_index / float(text_span)), \
  14. clear_time + dirty_time)
  15. matrix_time = 0.0 if matrix_time < clear_time else \
  16. (matrix_time - clear_time) / dirty_time
  17. if value >= 65 && value < 126 && matrix_time > 0.0:
  18. value -= 65
  19. value = value + int(1 * matrix_time * (126 - 65))
  20. value %= (126 - 65)
  21. value += 65
  22. char_fx.character = value
  23. return true

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

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