最近趣味でGodotEngineを触り始めている。
Godot Engine - Free and open source 2D and 3D game engine
新しい単語や概念が多いので、とりあえず備忘録として。
とにかく日本語の資料が少ない。
signalとは
文字通り信号を送る機能。
http://docs.godotengine.org/en/latest/getting_started/scripting/gdscript/gdscript_basics.html#signals
Godotではあらゆるイベントが発生した際にそれを通知するための仕組みがあり、それをシグナルと呼んでいる。
例えば衝突判定を扱うCollisionObject2Dは、3つのシグナルが存在している。
input_event
mouse_entered
mouse_exited
は同名のメソッドをスクリプトで書いたら勝手にコールバックとして呼ばれる。
Unityで言うOnCollisionほげほげメソッドを実装する感覚に近い。
そしてこのシグナルは、自分で定義して通知することができる。
シグナルを自作する
例えば以下を考えてみる
- Ankouノードは、任意のタイミングで「戦車前進」の通知を飛ばす
- Kameノードは、「戦車前進」の通知が来たら何かする
Ankouはシグナルを通知する側なのでこんな感じで書く
extends Node
# 自作シグナル
signal panzer_vor
func _ready():
# 自身の panzer_vor シグナルを受けとったら _on_panzer_vor にコールバック
connect("panzer_vor", self, "_on_panzer_vor")
# シグナルを送信する
emit_signal("panzer_vor")
func _on_panzer_vor():
print("Go Ankou")
やることは以下の三つ。
- シグナルの定義
- シグナルを受け取れるよう接続
- シグナルの送信
自作シグナルは signal hoge
で定義。
それを受け取れるよう connect
でシグナル名、受け取るオブジェクト、コールバック先を書く。最後に emit_signal
で送信する。
この時点でエディタ上で panzer_vor
シグナルが見えるようになる。
Kameさんノードはシグナルを受け取るためにAnkouと接続する必要があるが、それ以外は何も変わらない。
extends Node
func _ready():
var ankou_node = $Ankou
ankou_node.connect("panzer_vor", self, "_on_panzer_vor")
func _on_panzer_vor():
print("Go Kame")
通知を受け取るのをやめる場合、disconnect
メソッドを呼ぶと終了できる。
一度Connectしたものを再度Connectしようとするとデバッガでエラーが発生するがゲームは落ちない。
基本的にノード同士のやりとりはシグナルでやったほうが楽そう。
GUI上でシグナルを受け取る
上記の connect
に相当する部分はGUI上でも定義できる。
ここをダブルクリックするとウィンドウが出てくる
ノードを指定してコールバックメソッド名を書く。Make FunctionオプションをONにしたらメソッドを生成までやってくれる。
適切に設定完了すると、GUI上でコールバック先まで確認できるようになる。
動的に設定しないのであれば、ここで書いてしまった方がわかりやすいかもしれない。
Godotユーザ増えてほしい