【Godot】3秒後に処理する方法|TimerのtimeoutとOne Shot
この記事について
ボタンを押してから数秒後に処理したいときは、Timerノードを使うと待ち時間と完了処理を分けて書けます。この記事では3秒カウントダウンを作り、残り時間の表示、途中からの再開、最初からのやり直しを試します。
Godot 4.6.3のGDScriptを使い、エディターの項目名は英語表記で説明します。画面全体を停止するポーズ機能ではなく、Timerだけの一時停止です。
この記事でわかること
- TimerのWait TimeとOne Shotを設定する方法
- timeoutシグナルで待ち時間後の処理を実行する方法
- 残り時間を保った再開と、最初からのやり直しの違い
基本手順
完成サンプルはこちらのGodotプロジェクトZIPから開けます。ZIPを展開し、Project ManagerのImportでproject.godotを選んでください。自分で新規作成する場合は、レンダラーをCompatibilityにして進めます。
手順1:画面とTimerを作る
Scene → New Scene → User InterfaceからControlを作り、TimerUIへ名前変更してmain.tscnに保存します。TimerUIの子へVBoxContainerを追加してContent、別の子へTimerを追加してCountdownTimerと名付けます。TimerをContentの中に入れず、次の構成にそろえてください。
TimerUI (Control) ├ Content (VBoxContainer) │ ├ TitleLabel (Label) │ ├ StatusLabel (Label) │ ├ StartButton (Button) │ └ PauseButton (Button) └ CountdownTimer (Timer)
ContentのLayout → TransformでPositionをX=40、Y=40、SizeのXを640にします。Separationは16、文字のFont Sizeは24、ボタンのCustom Minimum SizeのYは48です。TitleLabelは「3秒カウントダウン」、StatusLabelは「開始ボタンを押してください」、StartButtonは「開始 / 3秒からやり直す」、PauseButtonは「一時停止」とします。PauseButtonのDisabledをオンにします。

手順2:待ち時間を3秒にし、1回だけ動かす
CountdownTimerを選び、InspectorのWait Timeを3、One Shotをオン、Autostartをオフにします。One Shotは時間切れで止める設定、Autostartはシーンへ入った時に自動で開始する設定です。今回はボタンで開始するためAutostartを使いません。

手順3:開始・一時停止・完了のコードを書く
TimerUIにres://main.gdをAttach Scriptで付け、Templateのチェックを外して作成します。次の内容を入力してください。ButtonのpressedとTimerのtimeoutはコードで接続するため、Signalsタブでは接続しません。
extends Control
@onready var timer: Timer = $CountdownTimer
@onready var status_label: Label = $Content/StatusLabel
@onready var pause_button: Button = $Content/PauseButton
var completed: int = 0
func _ready() -> void:
$Content/StartButton.pressed.connect(_start_countdown)
pause_button.pressed.connect(_toggle_pause)
timer.timeout.connect(_on_timeout)
func _process(_delta: float) -> void:
if not timer.is_stopped():
var state := "一時停止" if timer.paused else "カウント中"
status_label.text = "%s: 残り %.1f 秒" % [state, timer.time_left]
func _start_countdown() -> void:
timer.paused = false
timer.start()
pause_button.disabled = false
pause_button.text = "一時停止"
func _toggle_pause() -> void:
timer.paused = not timer.paused
pause_button.text = "再開" if timer.paused else "一時停止"
func _on_timeout() -> void:
completed += 1
status_label.text = "完了! timeout: %d 回" % completed
pause_button.disabled = true
pause_button.text = "一時停止"
_process()は実行中のtime_leftを表示するだけです。完了回数を増やす処理は_on_timeout()にまとめています。_start_countdown()はpausedを解除してstart()を呼びます。_toggle_pause()はpausedを切り替え、残り時間を保持します。

手順4:開始から完了までを確かめる
保存してF6で実行し、「開始 / 3秒からやり直す」をクリックします。残り時間が減り、約3秒後に「完了! timeout: 1 回」と表示されれば成功です。そのままさらに待っても回数は増えません。もう一度開始すると、次の完了時には2回になります。
独立したウィンドウで試す場合は、保存後にProject → Quit to Project Listへ戻り、Project Managerでこのプロジェクトを選んでRunを押します。独立実行を終えるときは、その実行ウィンドウを閉じます。
表示は小数第1位へ丸めているため、終了直前に「残り0.0秒」と見えることがあります。表示の丸めと完了通知は別です。完了の判定には文字や丸めた数値ではなくtimeoutを使います。

手順5:途中再開とやり直しを比べる
開始後、残り約2秒で「一時停止」をクリックします。残り時間が止まり、ボタンが「再開」へ変わります。数秒待って「再開」を押すと、止めた残り時間から動きます。
次にカウント中、または一時停止中に「開始 / 3秒からやり直す」を押します。今度は3秒へ戻って動きます。start()は残り時間の再開ではなく、カウントをリセットする操作です。一時停止中のTimerへstart()だけ呼んでもpausedは解除されないため、このコードでは先にfalseへ戻しています。

うまくいかないときの確認箇所
3秒ごとに何度も完了する
CountdownTimerのOne Shotを確認します。オフなら時間切れの後も繰り返すため、今回のサンプルではオンにしてください。コードとSignalsタブで同じ関数へ重複接続していないかも確認します。
実行直後に勝手に始まる
Autostartがオンになっていないか確認します。Autostartはノードがシーンツリーへ入ったときに動作し、実行時にはフラグが自動でfalseへ戻ります。Remote側でfalseになっていても、ローカルの保存済み設定がオフとは限りません。
一時停止後に開始ボタンを押しても動かない
timer.paused = falseがstart()より前にあるか確認します。またSceneTree全体をpausedにしている場合は、TimerのProcess Modeによって処理が止まります。このサンプルではSceneTree.pausedを使いません。
正確に3秒で表示が切り替わらない
Timerはフレーム更新に合わせて進むため、処理が重い環境では表示や通知に遅れが生じます。Engine.time_scaleを変更している場合も待ち時間へ影響します。実時間の精密な計測器として使うのではなく、ゲーム内の待ち時間を扱うものとして考えてください。stop()で途中停止してもtimeoutは発生しません。
まとめ
Timerの基本は待ち時間を設定し、start()で開始し、timeoutで完了処理を行うことです。1回だけならOne Shotをオンにします。pausedの切り替えは残り時間を保ち、start()は最初からやり直すという違いを押さえると、用途に合わせて操作を作れます。
サイトアイコン-2-150x150.png)