今回は、どのゲームでも実装されることの多い「シーンの切り替え」について紹介します。
ゲーム開発において必須の機能ですので、理解しておくと良いです。
【初心者向け】Godotでシーンを切り替える方法まとめ
シーン切り替えの基本:SceneTreeを使う
Godotでシーンを切り替えるときは、次のようなコードが基本になります。
get_tree().change_scene_to_file("res://scenes/Gameover.tscn")
get_tree()は、現在のシーンツリー(ゲーム全体)を取得します。そして、change_scene_to_file()で指定したシーンに切り替えます。
ボタンを押したらゲームオーバーシーンへ切り替える
という訳で例として、ボタンをクリックしたらゲームオーバーシーンに切り替える方法について解説したいと思います。
- ステージクリア後次のステージへ
- ゲームオーバー時にタイトルシーンへ
- タイトルシーンからメイン画面へ
このような用途によく使うんじゃないかと思いますね。
まずは、シーンを切り替える先となるゲームオーバー用のシーンを適当に作成します。
ルートノードはUIの基本となるControlノードで作っています。その中にゲームオーバーとテキストを表示するためにLabelノードを1つ作ります。
色や大きさ等は作成しているゲームに合わせる等お好みで調整してもらえればと思います。
func _on_button_pressed() -> void:
get_tree().change_scene_to_file("res://gameover.tscn")
後は、遷移元シーンにてボタンを作ってpressed()シグナルを適当なスクリプトに接続して上記のようなスクリプトを書けば準備は完了です。
res://の中はシーンの名前やシーンがある階層が異なるかもしれないので、適宜変えてくださいね。
ボタンの作り方や、シグナルに関しては前回の記事で解説しているので参考にしてください。
実際にシーン遷移元のシーンを実行して動作をチェックしてみましょう。
左上にあるのがボタンですね。そのボタンをクリックすると、ゲームオーバーシーンに切り替わっている事が分かりますね。
本来なら、敵にやられた時とかにシーンを切り替えるようにするとよりゲームらしくなるでしょう。
シーンを切り替える際にフェードアウトさせる
このままだと物足りないので、シーンが切り替わる際にフェードアウトさせるようにします。
ステージ上で画面を真っ暗にして次のシーンに切り替えたいので、ステージシーン上にCanvasLayerを作ります。これは、UIが他のノードの影響を受けないように使います。
その中に、RectColorノードを作って名前を「Fade」に変更します。
Fadeを画面いっぱいに広げてやり、インスペクターからColorの色を黒に変更します。また、透明度は最初「A=0.0(完全透明)」にしておきましょう。
続いて、Fadeの下にAnimationPlayerノードを作って名前をFadeAnimatorにします。
特定のタイミングで画面を暗くするアニメーションを再生して、その後別シーンに移行するイメージです。
このままだと、ColorRectが前面にあり元々作っていたボタンをブロックしてクリックしても反応しなくなってしまうので、変更を加えます。
FadeのインスペクターからMouseのFilterを「Ignore」に変えましょう。
続いて、FadeAnimatorを選択して下の「アニメーション」から新規アニメーションを作成しましょう。今回は、フェードアウトが目的なので分かりやすく「fade_out」という名前でアニメーションを作成しています。
続いて、透明度の値を変更することで1秒後に画面を真っ暗にする手順を行います。
手順が多いので、動画にしています。
ゲームを実行後アニメーションが自動再生されると困るので、「fade_out」の右にある読み込み後、自動再生は非アクティブにしておきます。
アニメーション後にシーンを切り替えるスクリプト
続いて、CanvasLayerに対してスクリプトを作ります。
extends CanvasLayer
@export var next_scene_path: String = "res://gameover.tscn"
@onready var fade_anim = $Fade/FadeAnimator
func fade_to_scene():
fade_anim.play("fade_out")
fade_anim.playにて再生させたいアニメーションを指定します。今回の場合は、先ほど作ったfade_outになりますね。
FadeAnimatorを選択して右のノード・シグナルから「animation_finished」シグナルをスクリプトがアタッチされているCanvasLayerに対して接続します。
extends CanvasLayer
@export var next_scene_path: String = "res://gameover.tscn"
@onready var fade_anim = $Fade/FadeAnimator
func fade_to_scene():
fade_anim.play("fade_out")
func _on_fade_animator_animation_finished(anim_name: StringName) -> void:
if anim_name == "fade_out":
get_tree().change_scene_to_file(next_scene_path)
最終的にスクリプトはこんな感じになります。
今回接続したシグナルは、アニメーションが最後のフレームまで再生し終わった瞬間に発生するシグナルです。
ですから、フェードアウトが終了次第、指定したパスのシーンへ切り替えるようになります。
後は、ボタンクリック時にこのスクリプトのfade_to_scene()を呼び出すようにしてあげればOKですね。
「@onready var fadeout = $”../CanvasLayer”」でCanvasLayerを取得してpressed()の中を「fadeout.fade_to_scene()」と変更すれば良いですね。