ゲーム制作勉強中!あこがれだったプログラマーに今からなろう!

昔、あこがれていたプログラマー。今からでも勉強してみようと思い立ち、チャレンジ開始! 勉強メモや、悪戦苦闘な日々の記録です。

Unity経験者のGodotの遊び方:Signalについて


Signals(シグナル)

今日は、Godotの4大要素の一つのSignals(シグナル)の引数について実験してみたので、その結果を踏まえてSignals(シグナル)について簡単にまとめておこうと思います。

Signalは、何か特定のイベントが発生した時に、指定しておいた関数を実行する仕組みです。
関数に引数を渡すこともできます。

このあたりはボタンの作成をUnityGodotで比較してみると、割と簡単に理解できると思います。

ボタンで確認する

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が接続され、ボタンをクリックするとこの関数が実行される様になります。

細かな操作は違いますが「ボタンを押す。」という機能だけで言えば、基本的にUnityGodotで大きな違いは無い様に感じます。
ただ、GodotSignalは、単にボタン操作だけではありません。


カスタムシグナル

スクリプトを使って、下記の様に独自の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