🔤

【Godot Engine】カスタムBBCodeタグの作り方【GDScript】

2024/11/01に公開

Godot Engine 4.3

はじめに

RichTextLabelノードではBBCodeタグを使用して多様なテキストエフェクトを実装できます。
デフォルトで用意されているタグだけでも大抵のことは実現できそうな感じですが、この記事では独自のBBCodeタグを作ってテキストエフェクトを作る方法を紹介します。

基本的な作り方

独自のBBCodeタグでテキストエフェクトを作るにはRichTextEffectクラスの_process_custom_fxメソッドをオーバーライドしてCharFXTransformクラスであるchar_fxのプロパティを変更することで実現可能となります。

_process_custom_fxはブール値を返す必要があり、テキストエフェクトを反映させるにはtrueを返す必要があります。逆にfalseが返されるとテキストに何も影響を与えなくなります。
また、BBCodeのタグ名はbbcodeという変数名で宣言される必要があります。

それでは単純なテキストエフェクトから作ってみましょう。
ここではテキストを黄色にハイライトするだけのBBCodeタグhighlightを作ります。
手順は以下の通りです。

  1. リソースの新規作成でRichTextEffectを選択。ここではcustom_bbcode.tresとする
  2. スクリプトの新規作成。ここではcustom_bbcode.gdとする。コードは以下の通り
custom_bbcode.gd
extends RichTextEffect

var bbcode := "highlight"

func _process_custom_fx(char_fx: CharFXTransform) -> bool:
	char_fx.color = Color.GOLD
	return true
  1. custom_bbcode.tresのインスペクタからScriptcustom_bbcode.gdをアタッチ

  2. RichTextLabelノードのMarkUp -> CustomEffectscustom_bbcode.tresを追加

基本的な手順は以上です。
あとはRichTextLabelノードのBBCode Enabledをオンにして試してみましょう。

Hello [highlight]Godot[/highlight] Engine


それっぽいものを作る

もう少しテキストエフェクトらしいものを作ってみましょう。
ここでは次のようにテキストをt秒間隔で1文字ずつ表示させるBBCodeタグtw_charを作ります。
Tweenvisible_charactersを補間するイメージです。

Hello [tw_char tick=0.5]Godot[/tw_char] Engine


引数はchar_fx.envからDictionaryとして取得できます。
getメソッドは引数が与えられなくてもデフォルトの値を受け取ることができて便利なので活用しましょう。

スクリプトは以下の通りです。

custom_bbcode2.gd
extends RichTextEffect

var bbcode := "tw_char"

func _process_custom_fx(char_fx: CharFXTransform) -> bool:
	char_fx.color.a = 0.0
	var env: Dictionary = char_fx.env
	var tick: float = env.get("tick", 1.0)
	if is_equal_approx(tick, 0.0):
		return false
		
	var visible_char_count := int(char_fx.elapsed_time / tick)
	if char_fx.relative_index < visible_char_count:
		char_fx.color.a = 1.0
	return true

このように独自のテキストエフェクトを実装するのに必要なプロパティは揃っていますので、公式ドキュメントの方も参考にしてみてください。
https://docs.godotengine.org/en/stable/classes/class_charfxtransform.html

また、BBCodeは入れ子にすることもできます。入れ子にするにはBBCodeごとにリソースを作成してCustomEffectsに追加していきます。

Hello [tw_char tick=0.5][highlight]Godot[/highlight][/tw_char] Engine


char_fxのプロパティについて個人的メモ

手を動かして分かった範囲でメモしておきます。公式ドキュメントも併せて参考に。

プロパティ メモ
env Dictionary 引数を取得できる。引数を文字列として受け取る場合、空白があってはならない(クォーテーションで囲まれていても)。受け取った値は形式に応じて型変換される。getメソッドを活用するのがよい
color Color
elapsed_time float 経過時間。単位は秒
font RID フォントのRID。フォントの変更もできるはず...
glyph_count int 書記素クラスタのグリフ数。例えば🇯🇵はU+1F1EFU+1F1F5からなるなので2
glyph_flag int 文字の種別判定。空白なのか、タブ文字なのかといったことなどを判別可能
glyph_index int グリフのインデックス。フォントによって異なる。デフォルトのフォントだとaが68でbが69
offset Vector2 文字の描画位置に対するオフセット。文字の位置をずらしたいときに変更する
outline bool trueならFX Transformはアウトラインの描画に呼び出されている...とのこと。アウトラインの有無に関わらずtruefalseが返されるのでよくわからない...
range Vector2i 文字の範囲。例えば[test]abc[/test]ならabcの範囲はそれぞれ(0, 1),(1, 2),(2, 3)であり123[test]abc[/test]なら
abcは(3, 4),(4, 5),(5, 6)
relative_index int 文字の相対的なインデックス。123[test]abc[/test]ならaが0
transform Transform2D デフォルト値はTransform2D(1, 0, 0, 1, 0, 0)
つまり
transform.x == Vector2(1, 0)
transform.y == Vector2(0, 1)
transform.origin == Vector2(0, 0)
ということ。いろいろ応用できそう...
visible bool trueで文字を表示。falseなら非表示

Discussion