「3秒待ってから敵を出したい」「攻撃アニメーションが終わってからダメージ判定したい」「会話の次の行 はボタン入力まで待ちたい」。こういう処理を全部 _process() のタイマー変数で書くと、すぐに見通しが悪くなります。
Godot 4の await は、こうした 一連の流れの途中で待つ処理 を読みやすくするための道具です。ゲーム全体を止めるのではなく、その関数だけを一時停止し、条件がそろったら続きから再開します。
この記事でわかること
awaitが「何を止めて、何を止めないのか」- タイマー、アニメーション、会話での実用例
connect()とawaitの使い分け- Godot 3の
yieldからGodot 4のawaitへの読み替え
awaitは「この関数だけ待つ」仕組み
await は、待機対象が完了するまで 今の関数の続きを一時停止 します。その間も、Godotの描画、入力、物理処理、他ノードの _process() は動き続けます。

たとえば次のコードは、3秒待ってから敵を出します。
func spawn_enemy_after_countdown() -> void:
print("3秒後に敵が出ます")
# timeoutシグナルが出るまで、この関数の続きだけを待つ
await get_tree().create_timer(3.0).timeout
spawn_enemy()
await の行で関数は止まりますが、ゲーム自体は止まりません。プレイヤーの入力受付、画面描画、他の敵の移動は続きます。
このように、途中で止まって後から再開できる関数を コルーチン と呼びます。難しく聞こえますが、Godotでは「await を含む関数」と考えれば十分です。
ゲーム開発で使う場面
await が向いているのは、時間や演出の順番 がある処理です。

- アクション: 攻撃ボタン → 攻撃アニメーション終了待ち → 当たり判定 → クールダウン。
- RPG: セリフ表示 → 決定ボタン待ち → 次のセリフ表示。
- ステージ開始: カウントダウン → 3秒待機 → プレイヤー操作を有効化。
どれも「毎フレームずっと監視する」というより、流れを上から順に読みたい処理 です。こういう場面では、await を使うとコードがかなり自然になります。
タイマーを待つ
一定時間待つには、get_tree().create_timer() で一時的なタイマーを作り、その timeout シグナルを待ちます。

func start_stage() -> void:
# 1秒ごとに表示を変えるので、カウントダウンの流れが上から読める
$CountdownLabel.text = "3"
await get_tree().create_timer(1.0).timeout
$CountdownLabel.text = "2"
await get_tree().create_timer(1.0).timeout
$CountdownLabel.text = "1"
await get_tree().create_timer(1.0).timeout
$CountdownLabel.text = "START"
# 待機が終わってから操作を有効にする
player.can_control = true
Timer ノードをシーンに置かなくても、短い待機ならこの書き方で十分です。ステージ開始、リスポーン待ち、攻撃後のクールダウンなどに使いやすいです。
ただし、何百体もの敵がそれぞれ create_timer() を大量に作るような設計は避けます。大量の個体管理では、共通のクールダウン管理やステートマシンの方が見通しが良くなります。
アニメーションやシグナルを待つ
await は、シグナルを待つ処理と相性が良いです。たとえば攻撃アニメーションが終わってから、次の処理へ進めます。
func perform_slash_attack() -> void:
# 攻撃中の二重入力を防ぐ
can_input = false
$AnimationPlayer.play("slash")
# 攻撃アニメーションが終わるまで次へ進まない
await $AnimationPlayer.animation_finished
apply_slash_damage()
# 演出後に入力を戻す
can_input = true
このコードは「入力を止める → slashを再生 → 終了を待つ → ダメージ判定 → 入力を戻す」と上から読めます。
会話でも同じ考え方が使えます。ボタンが押されたことをシグナルで通知し、そのシグナルを await します。
signal next_requested
func show_dialogue(lines: Array[String]) -> void:
for line in lines:
$DialogueBox.text = line
# プレイヤーが決定入力するまで次の行を表示しない
await next_requested
$DialogueBox.hide()
func _unhandled_input(event: InputEvent) -> void:
if event.is_action_pressed("ui_accept"):
next_requested.emit()
ここで重要なのは、await は「一度待って、進む」ための書き方だということです。ボタンが押されるたびに毎回処理したい場合は、次の connect() の方が向いています。
実例:ジャンル別にawaitを組み込む
ここまでで、create_timer() で時間を待つ方法と、animation_finished や独自シグナルを待つ方法を見ました。ここからは、その基本を実際のゲーム機能へどう組み込むかを見ていきます。
await は単に「待てる」だけではありません。ゲームの中で「この順番で起きてほしい」という演出やルールを、実装手順としてそのままコードに落とし込めるのが強みです。
アクションRPGの攻撃シーケンス
たとえばアクションRPGで剣攻撃を作るなら、やりたいことは「ボタンを押した瞬間にすぐダメージ」ではありません。

攻撃らしく見せるには、次のような順番が必要です。
- 攻撃中の連打や移動を止める。
- 振りかぶりのアニメーションを少し見せる。
- 当たり判定を短い時間だけ有効にする。
- 攻撃後の硬直を入れる。
- 入力を戻す。
await を使うと、この手順を上から順に書けます。
func perform_sword_attack() -> void:
if not can_input:
return
# 攻撃中は移動や再攻撃を受け付けない
can_input = false
$AnimationPlayer.play("sword_attack")
# 振りかぶりを少し待ってから、当たり判定を出す
await get_tree().create_timer(0.12).timeout
$SwordHitbox.monitoring = true
# 判定は短い時間だけ有効にする
await get_tree().create_timer(0.08).timeout
$SwordHitbox.monitoring = false
# 攻撃アニメーション全体が終わってから、入力を戻す
await $AnimationPlayer.animation_finished
can_input = true
この順番にする理由は、プレイヤーの操作感とゲームルールを両方守るためです。入力を止めないと、攻撃中にもう一度攻撃が始まり、アニメーションや判定が重なります。判定を出しっぱなしにすると、剣を振っていない時間にも敵へ当たります。後隙を待たずに入力を戻すと、攻撃を連打できすぎて、アニメーションの重みがなくなります。
変えるなら、まず待ち時間を調整します。軽い短剣なら予備動作と後隙を短く、重い斧なら長くします。コンボを作る場合は、最後にすぐ can_input = true にせず、「次の攻撃入力を受け付ける短い窓」を別のフラグで用意すると管理しやすくなります。
タワーディフェンスのウェーブ開始
タワーディフェンスでは、「いきなり敵が出る」よりも、警告、カウントダウン、間隔を空けた出現がある方がプレイヤーに準備の余地が生まれます。
