概要
このページではテキストスクロールを実装する方法について書きます。
→※追記 2021/2/18: ここで紹介している方法を使わなくても RichTextLabel
を使うことで簡単にテキストスクロールは実装できます。
テキストスクロールの実装
各種ノードの追加
ノードは以下のような構成となります。
ScrollContainer
+-- VBoxContainer
+-- Label
まずはシーンのルートノードに ScrollContainer
を追加します。
次に、ScrollContainerの子ノードとして VBoxContainer
を追加します。
VBoxContainerの子に Label
を追加します。
ScrollContainerのサイズを調整
テキストの実際の表示エリアとなる ScrollContainer
のサイズを設定します。
-
Rect > Position > x
: 60 -
Rect > Position > y
: 50 -
Rect > Size > x
: 160 -
Rect > Size > y
: 80
Labelにテキストを設定
スクロール確認用として以下のテキストを Label
ノードの Text
に設定します。
One
Two
Three
Four
Five
Six
Seven
Eight
Nine
Ten
あとは実行してスクロールの動作を確認します。
スクロールバーをマウスカーソルで動かしたり、テキストの上でマウスホイールを動かしたり、トラックパッドでスクロールさせることができます。
スマートフォン向け対応をする
動作は確認していませんが、スマートフォンだとスワイプでテキストが動作しないことがあるようです。
Containerの下に Containerが存在すると、スクロール処理をそちらに奪われてしまうとのことです。
ここでは、VBoxContainer
が悪さをする可能性があるので、VBoxContainer
の Control > Mouse > Filter
を Ignore
にしておくと、スマートフォンでも正常に動作しそうです。
スクリプトからログテキストを追加する
最後にスクリプトからテキストを追加する処理のサンプルです。
ScrollContainer
にスクリプトをアタッチして以下のように記述します。
extends ScrollContainer
const MAX_LOG = 10 # 10件を最大とする
# Spaceキーを押した回数
var cnt = 0
# ログ
var logs = []
# ラベルノードを取得
onready var label = $VBoxContainer/Label
func _process(delta):
if Input.is_action_just_pressed("ui_accept"):
# Spaceキーを押したらログを追加
logs.append(str(cnt))
cnt += 1
if logs.size() > MAX_LOG:
# 最大数を超えていたら先頭のログを削除
logs.pop_front()
# テキスト初期化
label.text = ""
var is_first = true
for s in logs:
if is_first:
is_first = false
else:
# 最初の行以外は改行を入れる
label.text += "\n"
label.text += s
Spaceキーを押した回数をログに追加する処理となります。
ログの最大件数は 10件として、それを超えた場合は一番古いログを消すようにしています。
追記
この記事を書いた後で気がついたのですが、RichTextLabel
を使用すると、ScrollContainer
を使わなくてもスクロールできることがわかりました
/(^o^)\ナンテコッタイ
RichTextLabelの「BB Code」について
せっかくなので、RichTextLabel
について調べました。
RichTextLabel では 「BB Code」という特殊な記法でテキストの装飾とアニメーションをすることができます。
BB Codeを有効にする
BB Codeを有効にするには、Bb Code > Enabled
にチェックを入れます。
BB Codeを有効にすると通常のテキストは使用できず、BB Codeのテキストのみ使用できます。
BB Codeの種類
公式ドキュメントに詳しく書いてあるので、説明は不要かもしれませんが、個人的な勉強のためにまとめておきます。
####色を変える [Color]
色を変えるには、テキストを[color]
で囲みます
This is [color=yellow]banana[/color].
このように記述すると、以下のように色が変わります
[color]
で囲んだ部分だけ色が変化します。
色の数は以下が用意されています。
- aqua: 水色
- black: 黒色
- blue: 青色
- fuchsia: 赤紫色
- gray: 灰色
- green: 緑色
- lime: 明るい緑色
- maroon: あずき色
- navy: 濃紺
- purple: 紫色
- red: 赤色
- silver: 銀色
- teal: 青緑色
- white: 白色
- yellow: 黄色
上記に存在しない色は16進数で指定します。
例えばオレンジ色だと……
This is [color=#FFA500]orange[/color].
画像を表示する [img]
アイテムアイコン画像を表示するなど、テキスト内に画像を表示したい場合は [img=幅]画像のパス[/img]
を使用します。
He is [img=16]res://icon.png[/img].
このように Godotくんをテキスト内に表示することも可能です。
ただ、サイズがテキストの高さよりも大きい場合、テキストの高さがずれてしまうので注意です。
アニメーション
[Wave]
波のアニメーション
[wave amp=50 freq=2]Wave Effect[/wave]
ampの値を大きくするほど上下移動が大きくなり、freqの値を大きくするほど上下の移動速度が上昇します。
上下移動で描画領域外に出てしまうとテキストが消えてしまうので、上下に1行ほど余裕をもたせたほうが良いかもしれません。
[Tornado]
竜巻のアニメーション
[tornado radius=5 freq=2]Tornade Effect[/tornado]
radiusは回転する半径の大きさ、freqは回転速度となります。
このアニメーションは上下左右に移動するので、上下左右の余白を大きくする必要がありそうです。
[Shake]
揺れ
[shake rate=20 level=10]Shake Effect[/shake]
テキストがガクブルします。 rateが揺れの速度で、levelが揺れ幅となります。
[Fade]
フェード
[fade start=4 length=14]Fade away effect[/fade]
フェードと色変えは組み合わせて表示できない(合成されない)ようです。
[fade start=4 length=14]Fade away [color=red]effect[/color][/fade]
合成するには、カスタムエフェクトで新しくタグを作る必要があるのかもしれません……。
以下の動画が詳しそう……
https://www.youtube.com/watch?v=o-cLQ7J1mc8
BB Codeのカスタムエフェクト
上記動画をもとに、カスタムエフェクトを試してみました。
BB Codeのカスタムエフェクトは、新規スクリプトを作成して
↓↓↓
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
上記コードを CustomGhostEffect.gd
として「名前をつけて保存」
すると、RichTextLabel
から RichTextGhost
(スクリプト内で指定した class_name
)を選べるようになり [ghost]
タグが使えるようになります。
以下のBB Codeをテストしてみます。
[ghost freq=5 span=5]ghost effect [/ghost]
[ghost]
のカスタムエフェクトが動くようになりました!