俺に解るように説明する "Godot Engine 3.x" 入門+

ゲームエンジン Godot Engine に関すること。入門とか使い方とかチュートリアルとか、あれとかこれとか。日本語解説。

"Godot Engine" GDScript 9 「change_scene() でシーン・チェンジ」

「ボタンを押すと、シーンが変わる」という一連の動作が出来るようになったので、書いておこうと思う。「ボタンを押す」 > 「シグナルが出る」 > 「何かする」 という一連の手順は以前やったが、おさらいしながら進む。

シーンとボタンを準備しよう

[1] 新しいプロジェクトを作成して、シーンを2つに。[メニュー] > [Scene] > [New Scene] で空のシーンが2つある状態に。

f:id:ore2wakaru:20170823120526p:plain

[2] 各シーンを以下のように作る。(ラベルノードとボタンノードの "Text" プロパティはお好きに) シーンにノードを置いていない状態ではセーブできないので、ノードを置いてから、[Ctrl] + [S] で名前を付ける。

f:id:ore2wakaru:20170823122751p:plain

[3] 「シーンAAAA」に置いたボタンにスクリプトを付ける。スクリプトの中身はなにもいじらなくてOK。

信号受信ノードにスクリプトを付けるのが、最初に行う準備だった。今回は、信号を出すのも受けるのも同じボタンノードで行うので、ここにスクリプトを付ける。だがこれは、信号を出すから付けているのではなく、あくまで受信するからである事に注意。

f:id:ore2wakaru:20170823125737p:plain

[4] 信号送信の準備をする。ノードパネルに切り替えて、"pressed()" をダブルクリック。当然だが、シーンパネルでボタンノードが選択されている事。

f:id:ore2wakaru:20170823131421p:plain

[5] 確認窓が開く。信号受信は、信号発信をするボタンノードに付いているスクリプトなので、ちゃんと選んで、[接続]。

f:id:ore2wakaru:20170823132613p:plain

(おっと、"Method In Node" ってわざわざ「メソッド」書いてあるけど、関数って呼ぶ俺。俺はなんでもかんでも関数派。)

[6] [接続]するとスクリプトに、信号受信時に呼ばれる関数を追加してくれる。中身(ボディ)が空なので、pass というキーワードが入っている。

f:id:ore2wakaru:20170823133519p:plain

[7] スクリプトを修正。「シーンAAAA」では、ボタンを押すと「シーンBBBB」に変わるようにしたい。以下のように修正。

f:id:ore2wakaru:20170823234028p:plain

コピペ用

func _on_Button_pressed():
    get_tree().change_scene("res://BBBB.tscn")

【解説】

  • get_tree(): シーンツリー(Godot が用意している「Viewport」がいっこだけのアレ)を操作しますよ、って事。ボタンノードのスクリプトからは、いきなり SceneTree クラスで定義されている change_scene() 関数を呼べないので、get_tree() として、SceneTree クラスで定義されている関数を使えるようにしている、とも言える。Node クラスで定義されている。
  • change_scene(): シーンツリーに入っているノードを全部クリアして(Godot が用意している「Viewport」以外)、( ) 内のシーンにあるノードを追加しますよって事。SceneTree クラスで定義されている。
  • get_tree()change_scene() を "." (ドット)で繋ぐので注意。こうやって操作対象を先に指定して、"." を挟んでその後に操作を記述する表記がある。以前やった、get_node() もこれと同じ使い方をしている。(ドットシンタックス(dot syntax)、とか言うみたい)
  • "res://BBBB.tscn": ( ) 内で指定するシーンは、" " で挟んだパス名。"res://" は Godot 独自のプロジェクトフォルダを指す表現だった。
  • 忘れちゃいけないのが、get_tree() の前のインデント。関数のボディを書く時の立派な文法のひとつ。

[8] 同様の手順で「シーンBBBB」の方も「ボタンを押すと何かする」の操作を行う。スクリプトに修正をする部分が、"res://BBBB.tscn" から "res://AAAA.tscn" になるだけ。一応コピペ用

func _on_Button_pressed():
    get_tree().change_scene("res://AAAA.tscn")
出来たらシーンを再生してみよう

一応、[メニュー] > [Scene] > [Save all Scenes] で両シーンをセーブして、「シーンAAAA」をタブで指定してから(シーンBBBBでもいいけど)、右上ツールの [シーン再生] ボタンを押してみよう。

f:id:ore2wakaru:20170824010043p:plain

うむ。この仕組みをエアホッケーに組み込めばいいだけだ。だが・・・。



たまに、[Copy Path] がうまく働かない時があるんだが、仕様?