ダメージのポップアップ表示
この記事は Godot 3から Godot 4 へ内容の書き換え中です。 Godot4では存在しない変数、関数が含まれている場合があります。もしその場合はリポジトリのIssuesまでご報告ください。
課題
ダメージを受けたとき、数字を浮かせながら表示(Floating Combat Text)させたい。
解決策
この問題に取り組む方法は様々です。例えば、ビットマップフォントを使用し、各数字をその構成桁から画像として生成した上で、Sprite2Dノードを使って表示・移動させるといった手法が考えられます。
ただし、このレシピでは Label ノード(名前は「FCT」)を使用します。この方法であれば、フォントの変更が柔軟に行えるだけでなく、数字を文字列として表示するのも簡単になります。さらには状況に応じて「miss」などの他のメッセージを表示することもできます。
LabelSettings を追加し、お好みのフォントを使用します。“Xolonium.ttf” フォントを使用し、文字サイズを 28 ポイントに、アウトラインの色を黒、幅を 4 ピクセルに設定しています。
ラベルにスクリプトを追加してください。
extends Label
func show_value(value, travel, duration, spread, crit=false):
浮動テキストを出現させる際に、この関数を呼び出してパラメーターを設定します。
value- 表示する数値(または文字列)travel- 移動方向を表すVector2オブジェクトduration- テキストが表示される時間の長さspread- この角度範囲内でランダムに動きが拡散されるcrit-trueの場合、ダメージが「クリティカルヒット」であることを意味するフラグ
以下にこの関数の機能を説明します。
text = value
var movement = travel.rotated(rand_range(-spread/2, spread/2))
rect_pivot_offset = rect_size / 2
まず、指定された値を設定し、与えられたスプレッド範囲(例:±90度)に基づいて移動をランダム化します。スケーリングもアニメーション化する可能性があるため、制御点の中心からスケールが開始されるよう rect_pivot_offset を中央に設定します。
$Tween.interpolate_property(self, "rect_position",
rect_position, rect_position + movement,
duration, Tween.TRANS_LINEAR, Tween.EASE_IN_OUT)
$Tween.interpolate_property(self, "modulate:a",
1.0, 0.0, duration,
Tween.TRANS_LINEAR, Tween.EASE_IN_OUT)
次に、補間する2つのプロパティを設定します。移動用のpositionと、表示制御用のmodulate.aです。
if crit:
modulate = Color(1, 0, 0)
$Tween.interpolate_property(self, "rect_scale",
rect_scale*2, rect_scale,
0.4, Tween.TRANS_BACK, Tween.EASE_IN)
クリティカルヒットの場合、色も変更してスケールアニメーションを追加し、より印象的な演出にします。注:ここでは便宜的に赤色をハードコードしていますが、本来は設定可能な値とすべきです。
$Tween.start()
yield($Tween, "tween_all_completed")
queue_free()
最後に、Tween を開始し、処理が完了するまで待機した後、ラベルを削除します。
フロートテキストマネージャー
次に、浮遊テキストの表示位置を管理し生成するための小さなノードを作成します。このノードは、浮動テキストエフェクトを表示させたいゲームエンティティにアタッチされます。
これは Node2D クラスのノードで「FCTManager」という名前です。このノードには以下のスクリプトが含まれています。
extends Node2D
var FCT = preload("res://FCT.tscn")
@export var travel = Vector2(0, -80)
@export var duration = 2
@export var spread = PI/2
func show_value(value, crit=false):
var fct = FCT.instantiate()
add_child(fct)
fct.show_value(str(value), travel, duration, spread, crit)
以下の箇所では、設定内容をインスペクターに表示して簡単に変更できます。ここで定義されているshow_value()メソッドは、フローティングラベルを生成し、そのプロパティを設定します。
ゲーム内ユニットでは、このノードのインスタンスを作成して、テキストを表示させたい任意の位置に配置します。その後、ユニットの take_damage() メソッドに以下のようなコードを追加してください。
$FCTManager.show_value(dmg, crit)
まとめ
【最適化】多数の敵や弾が出現する場合、テキスト表示オブジェクトの頻繁な生成と破棄によりパフォーマンスが低下する可能性があります。この場合は、マネージャ内で固定数のテキストオブジェクトを生成し、アニメーション終了時に破棄するのではなく、表示/非表示を切り替える方法が有効です。
本デモで使用しているアートワークはLuis Zuno氏による作品です。
プロジェクトのダウンロード
以下からプロジェクトのサンプルコードをダウンロードできます。https://github.com/godotrecipes/floating_combat_text