この記事は Google 翻訳による英語翻訳の結果であり、これに DrGraph がいくつかの修正を加えたものです。英語のオリジナルページ:
シグナルの使用 — Godot Engine (安定版) ドキュメント (英語)
シグナルの使用¶
このレッスンでは、信号について学習します。これらは、ボタンの押下など、特定のイベントが発生したときにノードによって送信されるメッセージです。他のノードはこのシグナルに接続し、イベントの発生時に関数を呼び出すことができます。
シグナルは、Godot に組み込まれた委任メカニズムであり、あるゲームオブジェクトが相互に参照することなく、別のゲームオブジェクトの変更に反応できるようにします。シグナルを使用して結合を制限し、コードの柔軟性を保ちます。
たとえば、プレーヤーの健康状態を表す健康バーを画面上に表示するとします。プレイヤーがダメージを受けたとき、または回復ポーションを使用したとき、棒グラフにその変化を反映させたいと考えます。このために、Godot ではシグナルを使用します。
注: 冒頭で述べたように、シグナルはオブザーバー パターンの Godot バージョンです。詳細については、こちらをご覧ください: https://gameprogrammingpatterns.com/observer.html
ここで、信号を使用して、前のレッスン (プレーヤーの入力を聞く)で作成した Godot アイコンを移動し、ボタンを押して停止します。
シーン設定¶
ゲームにボタンを追加するには、ボタンと前のレッスンで作成したシーンを含む新しいメイン シーンを作成しますSprite2D.tscn
。
メニューの「シーン」→「新規シーン」に移動して、新しいシーンを作成します。
シーン ドックで、2D シーン ボタンをクリックします。これにより、Node2D がルートとして追加されます。
FileSystem ドックで、以前に保存したファイルをクリックしてSprite2D.tscn
Node2D にドラッグし、インスタンス化します。
Sprite2D の兄弟として別のノードを追加したいと思います。これを行うには、Node2D を右クリックし、[子ノードの追加] を選択します。
Button ノード タイプを検索して追加します。
デフォルトでは、このノードは小さいです。ビューポート内のボタンの右下隅にあるハンドルをクリックしてドラッグし、サイズを変更します。
ハンドルが表示されない場合は、ツールバーで選択ツールがアクティブであることを確認してください。
ボタン自体をクリックしてスプライトに近づけてドラッグします。
インスペクターで Text プロパティを編集して、ボタンにラベルを書き込むこともできます。「トグルモーション」[トグルモーション]と入力します。
シーン ツリーとビューポートは次のようになります。
新しく作成したシーンを保存します。その後、F6 (macOS では Cmd + R) を押して実行できます。現時点ではボタンが表示されていますが、現時点では押しても何も起こりません。
エディターで信号を接続する¶
ここでは、ボタンの「押された」信号を Sprite2D に接続し、そのモーションをオンまたはオフにする新しい関数を呼び出します。前のレッスンで行ったように、スクリプトを Sprite2D ノードにアタッチする必要があります。
ノードドックで信号を接続できます。Button ノードを選択し、エディターの右側で、インスペクターの隣にある「ノード」というタブをクリックします。
ドックには、選択したノードで利用可能な信号のリストが表示されます。
「押された」信号をダブルクリックして、ノード接続ウィンドウを開きます。
そこで信号を Sprite2D ノードに接続できます。このノードには、ボタンが通知されたときに Godot が呼び出す関数であるレシーバー メソッドが必要です。エディターが自動的に生成します。慣例により、これらのコールバック メソッドに「_on_node_name_signal_name」という名前を付けます。ここでは、「_on_button_pressed」という名前を付けることができます。
注: エディターのノード ドックを介して信号を接続する場合、2 つのモードを使用できます。Simple では、スクリプトがアタッチされているノードに接続し、そのノード上に新しいコールバック関数を作成することができます (上記)。
詳細ビューでは、任意のノードおよび任意の組み込み関数に接続し、コールバックにパラメータを追加し、オプションを設定できます。ウィンドウの右下隅にある「詳細」ボタンをクリックすると、モードを切り替えることができます。
[接続] ボタンをクリックして信号接続を完了し、スクリプト ワークスペースにジャンプします。左余白に接続アイコンが付いた新しいメソッドが表示されます。
アイコンをクリックすると、接続に関する情報が表示されたウィンドウが表示されます。この機能は、エディターでノードを接続する場合にのみ使用できます。
pass
キーワードが含まれる行を、ノードの移動を切り替えるコードに置き換えてみましょう。
Sprite2D は_process()
関数内で移動されます。Godot は、[_process 関数] 処理をオンまたはオフにする方法を提供します: Node.set_process()。現在アイドル状態である場合にis_processing()
返すNode クラスの別のメソッドtrue
。not
キーワードを使用してその逆数値を取得できます。
func _on_button_pressed(): set_process( is_processing()ではありません)
この関数は、ボタンが押されたときにアイコンのオンとオフを切り替える [__process] のアクションを切り替えます。
ゲームを試す前に、_process()
ユーザーの入力を待つのではなく自動的にノードを移動するように関数を簡素化する必要があります。これを、2 つ前のレッスンで見た次のコードに置き換えます。
関数_プロセス(デルタ): 回転 += 角度速度 * デルタ var速度 = Vector2.UP.rotated(回転) * 速度 位置 += 速度 * デルタ
完全なsprite_2d.gd
コードは次のようになります。
Sprite2Dを拡張します var速度 = 400 var angular_speed = PI 関数_プロセス(デルタ): 回転 += 角度速度 * デルタ var速度 = Vector2.UP.rotated(回転) * 速度 位置 += 速度 * デルタ func _on_button_pressed(): set_process( is_processing()ではありません)
次に、シーンを実行し、ボタンをクリックして、スプライトの開始と停止を確認します。
コードを介して信号を接続する¶
エディターを使用する代わりに、コードを介して信号を接続できます。これは、スクリプトでノードを作成したり、シーンをインスタンス化したりするときに必要です。
ここでは別のノードを使用してみましょう。Godot には、スキルのクールダウンや武器のリロードなどを実装するために使用できるタイマーノードがあります。
2D ワークスペースに戻ります。ウィンドウの上部にある「2D」テキストをクリックするか、Ctrl+F1 (macOS では Alt+1) を押します。
シーン ドックで Sprite2D ノードを右クリックし、新しい子ノードを追加します。Timer を検索し、対応するノードを追加します。シーンは次のようになります。
Timer ノードを選択した状態で、インスペクターに移動し、Autostart プロパティを有効にします。
Sprite2D の横にあるスクリプト アイコンをクリックして、スクリプト ワークスペースに戻ります。
コードを通じてノードを接続するには、次の 2 つの操作を行う必要があります。
-
Sprite2D からタイマーへの参照を取得します。
-
connect()
このメソッドは、タイマーの「タイムアウト」信号で呼び出されます。
注: コードを通じて信号に接続するには、connect()
リッスンする信号のメソッドを呼び出す必要があります。この場合、タイマーの「タイムアウト」信号をリッスンする必要があります。
シーンをインスタンス化するときに信号を接続する必要があります。これは、ノードが完全にインスタンス化されるとエンジンによって自動的に呼び出されるNode._ready()組み込み関数を使用して実行できます。
現在のノードに相対的なノード参照を取得するには、 Node.get_node()メソッドを使用します。参照を変数に保存できます。
func _ready(): var timer = get_node("タイマー")
この関数は、get_node()
Sprite2D の子ノードを調べ、名前でノードを取得します。たとえば、エディターで Timer ノードの名前を「BlinkingTimer」に変更した場合、呼び出しを に変更する必要がありますget_node("BlinkingTimer")
。
これで、関数内で Timer を Sprite2D に接続できるようになりました _ready()
。
func _ready(): var timer = get_node("タイマー") timer.timeout.connect(_on_timer_timeout)
行は次のようになります: タイマーの「タイムアウト」信号をスクリプトが接続されているノードに接続します。タイマーが発行されると、現在定義する必要があるtimeout
関数を呼び出します。_on_timer_timeout(),该函数是
これをスクリプトの最後に追加し、それを使用してスプライトの表示/非表示を切り替えましょう。
注: 慣例により、これらのコールバック メソッドには、GDScript では「_on_node_name_signal_name」、C# では「OnNodeNameSignalName」という名前が付けられます。ここで、GDScript は「_on_timer_timeout」、C# は OnTimerTimeout() です。
func _on_timer_timeout(): 見える=見え ない
このvisible
プロパティは、ノードの可視性を制御するブール値です。この行はvisible = not visible
値を切り替えますvisible
。「はい」の場合はtrue
となり、そのfalse
逆も同様です。
ここでシーンを実行すると、スプライトが 1 秒間隔で点滅するのがわかります。
完全なスクリプト¶
移動して点滅する Godot アイコンの小さなデモはこれで終わりです。参照用の完全なsprite_2d.gd
ファイルは次のとおりです。
Sprite2Dを拡張します var速度 = 400 var angular_speed = PI func _ready(): var timer = get_node("タイマー") timer.timeout.connect(_on_timer_timeout) 関数_プロセス(デルタ): 回転 += 角度速度 * デルタ var速度 = Vector2.UP.rotated(回転) * 速度 位置 += 速度 * デルタ func _on_button_pressed(): set_process( is_processing()ではありません) func _on_timer_timeout(): 見える=見え ない
カスタム信号¶
注: このセクションは、独自の信号を定義して使用する方法に関するリファレンスであり、前のレッスンで作成したプロジェクトに基づいて構築されるものではありません。
スクリプトでカスタム信号を定義できます。たとえば、プレイヤーの体力がゼロになったときにゲームオーバー画面を表示したいとします。これを行うには、健康状態が 0 になったときに「死亡」または「健康状態が枯渇した」という信号を定義できます。
Node2Dを拡張します 信号の健全性_枯渇 変数の健全性 = 10
注: 信号は起こったばかりのイベントを表すため、通常は名前に過去時制の動作動詞を使用します。
信号は組み込み信号と同じように機能します。信号は [ノード] タブに表示され、他の信号と同様に接続できます。
スクリプトでシグナルを発行するには、emit()
signal を呼び出します。
func take_damage(量): 健康状態 -= 量 健康状態 <= 0の場合: health_depleted.emit()
シグナルでは、オプションで 1 つ以上のパラメーターを宣言できます。括弧内にパラメータ名を指定します。
ノードを拡張します シグナルhealth_changed(old_value, new_value) 変数の健全性 = 10
注: シグナル パラメーターはエディターのノード ドックに表示され、Godot はそれらを使用してコールバック関数を生成できます。ただし、シグナルを発行するときに任意の数の引数を発行することもできます。したがって、正しい値を出力するかどうかはあなた次第です。
シグナルで値を出力するには、関数に追加の引数として値を追加します emit()
。
func take_damage(amount): var old_health = health 健康状態 -= 量 health_changed.emit(old_health, health)
概要¶ _
Godot のどのノードも、ボタンを押すなどの特定のイベントが発生すると信号を発信します。他のノードを個々の信号に接続し、選択したイベントに反応することができます。
信号にはさまざまな用途があります。これらを使用すると、ゲーム ワールドに出入りするノード、衝突、エリアに出入りするキャラクター、インターフェイス要素のサイズの変更などに反応できます。
たとえば、プレイヤーの物理ボディが衝突シェイプに入ると、コインを表すArea2D がbody_entered
信号を送り、プレイヤーがコインを収集したことを知らせます。
次のセクション「初めての 2D ゲーム」では、完全な 2D ゲームを作成し、これまでに学んだすべてを実践します。
【DrGraph】: シグナルは Windows アプリケーションのメッセージに似ていますが、より単純です。Godot の設計思想の観点から見ると、シグナルはオブジェクトの一部のメッセージ (ノード、スクリプト、シーンなど) をオブジェクトの親オブジェクトの呼び出しに公開するだけです。これらのメッセージは、オブジェクトの一部のビジネス ロジックの機会 (瞬間) です。親オブジェクトがこれらの信号にバインドされている場合、親オブジェクトの対応する関数が、このオブジェクトの対応するビジネス ロジック モーメントで呼び出されます。これは親オブジェクトの内部呼び出しであるため、親オブジェクトの一部のプロパティが変更されると、親オブジェクトのビジネス ロジックに影響を与える可能性があります。