この記事で作るもの
「はじめる」を押すとタイトル画面からゲーム画面へ進み、ゲーム画面の「タイトルへ」を押すと戻る仕組みを作ります。Godot 4.5のGDScriptを使い、2つのControlシーンに同じスクリプトを付けます。
ここでいうシーンの切り替えは、現在のシーンを新しいシーンに置き換えることです。元の画面を非表示のまま残す操作ではありません。戻ったときにはタイトルシーンが新しく作られます。
1. 2つのシーンを保存する
FileSystemでscenesフォルダを作り、次の2ファイルを保存します。どちらもルートはControlです。ノード名はコードから参照するので、大文字と小文字も合わせます。
res://scenes/title.tscn
TitleScreen (Control)
Button ← Text: はじめる
StatusLabel (Label) ← Text: タイトル画面
res://scenes/level_01.tscn
LevelScreen (Control)
Button ← Text: タイトルへ
StatusLabel (Label) ← Text: ゲーム画面
各ルートをFull Rectにし、ButtonはPositionを(40, 80)、Sizeを(200, 48)、StatusLabelはPositionを(40, 24)にします。最初はゲーム本体を作り込まず、文字が切り替わる2画面で確かめます。
ルートのControlへ、次のスクリプトをSceneLink.gdとして付けます。2つ目のシーンでは新しいスクリプトを複製せず、同じファイルを割り当てます。
2. シグナルを受けて切り替える
extends Control
@export_file("*.tscn") var target_scene_path: String = ""
@onready var button: Button = $Button
@onready var status_label: Label = $StatusLabel
var switching := false
func _ready() -> void:
button.pressed.connect(_on_button_pressed)
func _on_button_pressed() -> void:
if switching:
return
if target_scene_path.is_empty():
status_label.text = "遷移先のシーンを設定してください。"
return
switching = true
button.disabled = true
status_label.text = "切り替え中…"
var error := get_tree().change_scene_to_file(target_scene_path)
if error != OK:
switching = false
button.disabled = false
status_label.text = "切り替え失敗。設定を確認してください。"
push_error("シーン切り替えエラー: %s (%s)" % [error, target_scene_path])
Buttonのpressedはコードで接続しています。エディタのシグナル一覧でも同じ関数へ接続すると二重に呼ばれるので、接続方法はコード側にそろえます。シグナルが初めてなら、GodotのSignalの基本も確認してください。
3. 遷移先をInspectorで指定する
各シーンのルートを選択し、InspectorのTarget Scene Pathでファイル選択ボタンを使います。@export_file("*.tscn")によって、シーンファイルを選べる項目になっています。
| 設定するシーン | Target Scene Pathで選ぶファイル | ボタンのText |
|---|---|---|
title.tscn | res://scenes/level_01.tscn | はじめる |
level_01.tscn | res://scenes/title.tscn | タイトルへ |
この値はシーンごとに保存されます。同じスクリプトを使っていても、遷移先は別々に設定できます。自分自身のシーンを指定すると、別画面へ進まず、その画面を作り直す動きになります。エクスポート項目の公式資料
最後にtitle.tscnをプロジェクトのメインシーンへ設定し、F5で実行します。メインシーンが未設定なら、最初の実行時にタイトルシーンを選びます。F6は編集中のシーンを実行する操作なので、ゲーム画面を開いているとそこから始まります。
4. 成功と失敗で処理を分ける
change_scene_to_file()は切り替えを受け付けるとOKを返し、ファイルを開けない場合などはエラー値を返します。失敗した場合にswitchingとbutton.disabledを戻すことで、失敗したままボタンを押せなくなることを防ぎます。原因を直すまでは、再び押しても同じエラーになります。
成功時は旧シーンがツリーから外れ、フレーム末尾で新しいシーンが追加されます。このため、呼び出し直後に同じスクリプトから新しい画面のノードを操作する構成にはしていません。画面を開いたときの初期化は、遷移先の_ready()などで行います。SceneTreeの公式資料
成功時のswitchingは元のシーンと一緒に破棄されます。遷移先は別のインスタンスなので、switching = falseから始まります。
「切り替え中…」は処理受付を示す文字です。この例は同期読み込みなので、その文字が実際に画面へ描画される前に切り替わる場合があります。大きなステージ向けの非同期ローディング画面や進捗表示は含めていません。
動作確認
| 確認すること | 期待する結果 |
|---|---|
| F5で起動する | 「タイトル画面」「はじめる」が表示される |
| 「はじめる」を押す | 「ゲーム画面」「タイトルへ」に変わる |
| 「タイトルへ」を押す | 新しいタイトル画面が表示される |
| Title側の遷移先を一時的に空にして実行する | 設定を促す文字が出て、画面は変わらない |
| 下の失敗テストを行う | エラーが出てボタンが再び押せる状態になる |
存在しないファイルはInspectorのファイル選択から選べないため、失敗テストでは実行を止め、コードのchange_scene_to_fileを呼ぶ1行だけを、元の行と同じ字下げで一時的に次へ変更します。Target Scene Pathは正しいファイルを設定したままにします。空にすると、その前の未設定チェックで処理が終わるためです。
var error := get_tree().change_scene_to_file("res://scenes/missing_scene.tscn")
missing_scene.tscnが存在しないことを確認し、保存してF5で実行します。「はじめる」を押した後もタイトル画面に残り、ボタンが押せることと、DebuggerのErrors欄にエラーが出ることを確認します。失敗の確認後は実行を止め、この1行を完成版のtarget_scene_pathを渡す形へ戻します。Inspectorの設定も編集画面で直した場合は、保存して実行し直します。Debuggerの公式資料
うまく動かないとき
- ButtonやStatusLabelが見つからない:ノードがルート直下にあり、名前が「1. 2つのシーンを保存する」のノード構成と一致するか確認します。
- 同じ画面に戻ってしまう:Target Scene Pathに、自分自身のシーンを指定していないか確認します。
- 戻ると画面内の値が初期化される:シーンが新しく作られるためです。持ち越す所持金や進捗は、Autoloadなど別の管理場所に保存する設計が必要です。
- クリックできない:ほかのControlが入力を遮っていないか確認し、まずは上の最小ノード構成で試します。
シーンそのものの役割を整理する場合は、NodeとSceneの基本へ戻れます。
この記事のまとめ
Godot 4.5のButtonとchange_scene_to_fileで2つの画面を往復します。ノード構成、遷移先の指定、連打防止、読み込み失敗時の復帰をコードと図で解説します。