【Godot Engine】カスタムBBCodeタグの作り方【GDScript】
Godot Engine 4.3
はじめに
RichTextLabel
ノードではBBCodeタグを使用して多様なテキストエフェクトを実装できます。
デフォルトで用意されているタグだけでも大抵のことは実現できそうな感じですが、この記事では独自のBBCodeタグを作ってテキストエフェクトを作る方法を紹介します。
基本的な作り方
独自のBBCodeタグでテキストエフェクトを作るにはRichTextEffect
クラスの_process_custom_fx
メソッドをオーバーライドしてCharFXTransform
クラスであるchar_fx
のプロパティを変更することで実現可能となります。
_process_custom_fx
はブール値を返す必要があり、テキストエフェクトを反映させるにはtrue
を返す必要があります。逆にfalse
が返されるとテキストに何も影響を与えなくなります。
また、BBCodeのタグ名はbbcode
という変数名で宣言される必要があります。
それでは単純なテキストエフェクトから作ってみましょう。
ここではテキストを黄色にハイライトするだけのBBCodeタグhighlight
を作ります。
手順は以下の通りです。
- リソースの新規作成で
RichTextEffect
を選択。ここではcustom_bbcode.tres
とする - スクリプトの新規作成。ここでは
custom_bbcode.gd
とする。コードは以下の通り
extends RichTextEffect
var bbcode := "highlight"
func _process_custom_fx(char_fx: CharFXTransform) -> bool:
char_fx.color = Color.GOLD
return true
-
custom_bbcode.tres
のインスペクタからScript
にcustom_bbcode.gd
をアタッチ
-
RichTextLabel
ノードのMarkUp
->CustomEffects
にcustom_bbcode.tres
を追加
基本的な手順は以上です。
あとはRichTextLabel
ノードのBBCode Enabled
をオンにして試してみましょう。
Hello [highlight]Godot[/highlight] Engine
↓
それっぽいものを作る
もう少しテキストエフェクトらしいものを作ってみましょう。
ここでは次のようにテキストをt
秒間隔で1文字ずつ表示させるBBCodeタグtw_char
を作ります。
Tween
でvisible_characters
を補間するイメージです。
Hello [tw_char tick=0.5]Godot[/tw_char] Engine
↓
引数はchar_fx.env
からDictionary
として取得できます。
get
メソッドは引数が与えられなくてもデフォルトの値を受け取ることができて便利なので活用しましょう。
スクリプトは以下の通りです。
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
このように独自のテキストエフェクトを実装するのに必要なプロパティは揃っていますので、公式ドキュメントの方も参考にしてみてください。
また、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+1F1EF とU+1F1F5 からなるなので2 |
glyph_flag | int | 文字の種別判定。空白なのか、タブ文字なのかといったことなどを判別可能 |
glyph_index | int | グリフのインデックス。フォントによって異なる。デフォルトのフォントだとa が68でb が69 |
offset | Vector2 | 文字の描画位置に対するオフセット。文字の位置をずらしたいときに変更する |
outline | bool |
true ならFX Transformはアウトラインの描画に呼び出されている...とのこと。アウトラインの有無に関わらずtrue とfalse が返されるのでよくわからない... |
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