【Godot】シグナルによるノード間の連携

作成: 2025-12-06

直接参照を避け、疎結合なコンポーネント設計を実現するGodotのシグナル機能の基本と実践

概要

Godotで開発を進めていると、ノード同士が連携する必要が出てきます。「プレイヤーがコインに触れたら、コインは消え、UIのスコアが上がる」といった場面です。初心者がやりがちなのは、プレイヤーのスクリプトからコインやUIのノードを直接参照(get_node()$を使う)してしまうことです。しかし、この方法はノード間の依存関係を強め、後々の変更を非常に困難にします。

この問題を解決し、ノード同士を「疎結合」に保つためのGodotの根幹的な仕組みがシグナル (Signals) です。

シグナルとは?「イベントが発生したよ!」という合図

シグナルとは、あるノードが「特定のイベントが発生した」ことを、他のノードに知らせるためのメッセージ(合図)です。シグナルを発信する側(Emitter)は、誰がそのメッセージを受け取るかを知る必要はありません。ただ合図を送るだけです。

一方、メッセージを受け取りたい側(Receiver)は、特定のノードの特定のシグナルを「購読(Connect)」しておきます。これにより、シグナルが発信されたときに、自身の特定のメソッド(Callback)が自動的に呼び出されます。

この仕組みにより、EmitterとReceiverは直接お互いを知らなくても連携できるのです。これは「関心の分離」として知られる、優れたソフトウェア設計の基本原則です。

シグナルの使い方:エディタでの接続

最も簡単で視覚的な方法は、Godotエディタを使ってシグナルを接続することです。

  1. シグナルを発信するノードを選択: シーンツリーで、シグナルを持つノード(例: Buttonノード)を選択します

  2. 「ノード」タブを開く: インスペクタの隣にある「ノード」タブを開き、その中の「シグナル」タブを選択します。すると、そのノードが発信できるシグナルの一覧が表示されます(例: pressed()

  3. シグナルを接続: 接続したいシグナル(例: pressed())をダブルクリックします。すると「シグナルを接続」ダイアログが開きます

  4. 受信者とメソッドを選択: ダイアログで、シグナルを受け取るノード(Receiver)を選択し、呼び出されるメソッド名を決定します(通常は自動生成される名前でOK)。「接続」ボタンを押せば完了です

これにより、Receiver側のスクリプトに、指定した名前のメソッドが自動的に生成されます。あとはそのメソッド内に、シグナルを受け取ったときの処理を記述するだけです。

# Receiver側のスクリプトに自動生成される
func _on_button_pressed():
    print("ボタンが押されました!")
    # ここに実行したい処理を書く

カスタムシグナルの定義と発信

Buttonpressedのように組み込みのシグナルだけでなく、自分で独自のシグナルを定義することも非常に重要です。

1. シグナルの定義: スクリプトの冒頭でsignalキーワードを使ってカスタムシグナルを宣言します。引数を渡すことも可能です。

# Player.gd
extends CharacterBody2D

# "health_changed"という名前のカスタムシグナルを定義
# 新しいHPの値を引数として渡せるようにする
signal health_changed(new_health)

var health = 100

func take_damage(amount):
    health -= amount
    # シグナルを発信する(Emitする)
    health_changed.emit(health)

    if health <= 0:
        die()

2. シグナルの発信: シグナルを発信したいタイミングで、signal_name.emit()メソッドを呼び出します。定義時に引数を指定した場合は、emit()にその値を渡します。

3. 接続: このカスタムシグナルも、組み込みシグナルと全く同じように、エディタの「ノード」タブから他のノード(例: UIのHPバー)に接続できます。HPバーのスクリプトは、health_changedシグナルを受け取ったら、渡されたnew_healthの値を使って表示を更新するだけで済みます。プレイヤーがどうやってダメージを受けたか、といった詳細を知る必要はありません。

まとめ

シグナルは、Godotにおけるノード間連携の最もクリーンで推奨される方法です。

  • 発信する側: 「イベントが起きた」と叫ぶだけ。誰が聞いているかは気にしない
  • 受信する側: 聞きたい合図を登録しておき、呼ばれたら自分の仕事をするだけ

この疎結合な関係を意識してコンポーネントを設計することで、シーンの再利用性が高まり、バグが少なく、変更に強いプロジェクトを構築できます。get_node()で親や兄弟を直接参照するコードを書いてしまったら、「これはシグナルで実現できないか?」と一度立ち止まって考えてみる癖をつけることが、Godotマスターへの第一歩です。