Godotでタッチが有効なGUIの作り方

Godotって何?

OSSゲームエンジン

godotengine.org

動作が軽い、プログラムも軽い(マック版で152MBちょい)、金が一切掛からないで最近のcacaponのお気に入り

最近、Godot4もBeta版をリリースしましたが、今回は3で確認しています。

こんなものを作りたい

cacapon.hatenablog.com

これをGodotでもできるようにしようと思いました。

結論

  • 透明のパネルコンテナを一番下に設置する。
  • 透明のパネルにあるgui_inputシグナルを親ノードに接続し、接続したコールバック関数に実装する。
  • プロジェクト設定からEnumlate Mouse From Touch をオンにしておく。*1

見た目とどんな感じで動くか

カチカチっと2回クリックしたのですが、パネル内ではタッチされたことが出力がされ、パネルの外だと反応していないことがわかります。

説明

今回行いたいのは限られた範囲のみにタッチの反応するGUIです。

そこで、GUIを一通り作ったのち、タッチ入力の作り方について調べることにしました。

タッチ入力を行うには?

docs.godotengine.org

公式ドキュメントによるとInputEventScreenTouch,InputEventScreenDragの二つを用いると、マウスのクリック、ドラッグと同様な形で実装できるようです。

こちらを参考に次のようなコードを作成しました。

extends PanelContainer

var i = 0

func _input(event: InputEvent) -> void:
    if event is InputEventScreenTouch:
        i+= 1
        print("touch %d" % i)

こちらを確認する前に、プロジェクト設定からEnumlate Mouse From Touch をオンにしておきましょう。

似たようなオプションが二つあるのですが、どちらかONになっていたらおそらく大丈夫です。


これを実行すると、クリックでタッチがカウントされることがわかります…

が、この実装だと、画面全体でクリックがカウントされてしまうため、GUI上でのみ反応できるようにする必要があります。

GUI上で入力を扱う時はgui_inputシグナルを使う

少し調べてたところ、Controlノードを継承したノードはgui_inputというシグナルを備えていることが分かりました。

printでデバッグ出力をした限りではありますが、入力を感知してくれるようです。

今回のパネルを作るにあたり、表面を覆う透明のパネルのgui_inputシグナルを使うことで対応しました。

透明のパネルを使用するわけ

初めは使わないで親ノードのgui_inputでタッチ確認をしていたのですが、なぜか一部しか反応しませんでした。

検証はできていませんが、おそらく親のパネルの上に子のコンテナが乗っているせいで、親のパネルをタッチできないのではないかと予想しました。

そこで、一番上に透明のパネルを置き、そのパネルからguiの入力を受け取ればいいのではないかと考えました。

ノードの構成と親ノードのコード

親ノードのコードで行なっているのはguiをタッチしたらカウントを増やしてデバッグ時出力しているだけです。

extends PanelContainer

var i = 0

func _on_TouchPanel_gui_input(event: InputEvent) -> void:
    if event.is_pressed():
        i+= 1
        print("touch %d" % i)

以上になります、ではまた来週お会いしましょう。

*1:もう一つのでもOKだが二つオンにすると2回タッチを認識されるので注意