Signals(シグナル)
今日は、Godotの4大要素の一つのSignals(シグナル)の引数について実験してみたので、その結果を踏まえてSignals(シグナル)について簡単にまとめておこうと思います。
Signalは、何か特定のイベントが発生した時に、指定しておいた関数を実行する仕組みです。
関数に引数を渡すこともできます。
このあたりはボタンの作成をUnityとGodotで比較してみると、割と簡単に理解できると思います。
ボタンで確認する
Unityの場合
まずはボタンによって呼び出される関数Aを、public関数として作成します。
この時点では、関数Aは完成させる必要はありませんが、最低限、public関数として宣言する必要があります。
次にボタンのインスペクターで、①の欄に、先ほど作成した関数Aを含むスクリプトがアタッチされたGameObjectを入れます。
そうすると、②の欄で関数Aが選択できます。
関数Aの宣言で、下のスクリプトの様にボタンから受け取る引数を予め指定しておくと、②の欄で関数を指定した時点で、そのすぐ下に、引数を入力するウィンドウも表示されます。
public class ButtonFunction : MonoBehaviour { public void ButtonClick(int value)//ボタンが押された時の関数をpublic関数・int型の引数を受け取ると宣言。 { Debug.Log(value); } }
これで、このボタンをクリックすると、関数Aが実行される様になります。
Godotの場合
Unityでは、ボタンによって呼び出される関数Aを先に作成しましたが、Godotではこの時点では、あってもなくても、どちらでも構いません。
まずは、ボタンのインスペクターから図の位置のノードをクリックします。
デフォルトで設定されているイベントのSignalの一覧が表示されます。
今回はボタンを押した時のSignalなので、pressed()
を選択してから、右下の接続
をクリックします。
「メソッドにシグナルを接続」というウィンドウが表示されますので、左下の高度な設定
をクリックします。
すると、図の様に「呼び出し引数を追加」という画面が表示された状態になります。
④をクリックして、関数に渡したい引数のタイプを(⑤)選択し、⑥の追加
をクリックします。
図の様に、引数を入力できる様になるので、受け渡したい値を設定します。
このSignalを受け取るスクリプトがアタッチされたノードを(⑦)クリックします。
実行したい関数が既にある場合は、選択
をクリックすると、⑦で指定したスクリプトの中の関数が表示されるので、その中から、実行したい関数を選択してから、接続
をクリックします。
実行したい関数がまだ存在しない場合は、関数を選択
せずに接続
をクリックします。
これで指定したスクリプトにSignalが接続され、ボタンをクリックするとこの関数が実行される様になります。
細かな操作は違いますが「ボタンを押す。」という機能だけで言えば、基本的にUnityとGodotで大きな違いは無い様に感じます。
ただ、GodotのSignalは、単にボタン操作だけではありません。
カスタムシグナル
スクリプトを使って、下記の様に独自のSignalを作ることもできます。
signal mysig(arg:int)#ここでは、int型の「呼び出し引数」の付いたカスタムシグナルを宣言しています。
このスクリプトがノードにアタッチされると、そのノードにカスタムシグナルが追加されます。
この様にして、簡単にカスタムシグナルを作成することができ、ボタンの時と同じ様に関数に接続することができます。
この接続もスクリプトを使う事で動的に行うこともできます。
mysig.connect(self._sig_test)#カスタムシグナルを接続する。
このメソッドを使うことで、カスタムシグナルをこのスクリプト(self)にある_sig_test
に接続する事ができます。
ただしカスタムシグナルは、あらかじめシステムが用意してくれているSignalと異なり、何かのイベントで自動的に
発信するようなことはありません。
発信もスクリプトで行います。
mysig.emit(10)#「呼び出し引数」をつけて、カスタムシグナルを発信する。
これで、自分専用のSignalを作成して、発信させたいタイミングでemit
することで、好きな関数を呼び出すこと
ができます。
システムのシグナルを動的に作成する
さらにスクリプトを使って、システムが用意してくれているSignalを、動的に作成して使用する事もできます。
extends Node var arg1=10#テスト用変数 func _ready(): var timer_node = Timer.new() #Timerノードを動的に作成 timer_node.wait_time = 0.5 #作成したTimerノードを0.5秒に設定 #Timerノードのtimeoutシグナルを、_on_timer_timeout関数に接続 timer_node.timeout.connect(_on_timer_timeout.bind(arg1))#bindで「呼び出し引数」を追加 add_child(timer_node)#Timerノードをシーンツリーに追加 timer_node.start()#Timerを開始する。
これで、システムのSignalを動的に作成して利用することもできます。
UnityでいうところのOn Collision Enter
のような基本の組み込み関数も、GodotではSignalになっています。
先ほどの下図にある様に、マウスがボタンの上に来た時にSignalを発してくれるmouse_entered
や、逆にマウスが離れた時のmouse_exited
など、UnityでいうEvent Systemのような機能まであります。
Signalを使って信号をやり取りする事で、シーン同士を連携させることができる様です。
参考サイト
zenn.dev