MENU

【Godot】Godotの主要概念(シーン・ノード・シグナル)

目次

シーン と シーンツリー

Godotにおける「シーン」は、一言で言うと(再利用可能な)ゲーム要素のまとまりです。
シーンは、ノードや別のシーンの組み合わせで構成されており、その階層構造が「シーンツリー」です。

シーンは、オブジェクト指向でいう「カプセル化」に相当する機能で、ゲームのパーツをある程度分離されたブロックのような形でまとめられる、以下のような特徴があります。

  • シーンはファイル ( .tscnファイル:PackedSceneリソース) として保存が可能
  • 保存したシーンは、他のシーン内でノードの子として追加(=インスタンス化)も可能

ノード

ノードはGodotにおいて基本となるゲームの構成要素で、機能別に定義されているクラスでもあります。

ノードには機能ごとに様々な種類がありますが、ノードの新規作成画面からも確認できるように、
すべてのノードはルートとなる「Node」クラスを継承しています。

特性/仕様

ノードについて、おさえておきたい特性と使用について、以下にまとめます。

• ノードは木構造を持ち、基本的に一つの親ノードを持つ(親のないノードはルートノード)
• 子のノードは親のTransformを継承する
• ノードはツリーの上位から順に描画される(下層のノードほど前面に表示)
• ルートノードはマネージャークラスとして捉えることができ、子ノードの作成と削除を管理

シグナル

シグナルは、「あるオブジェクトでイベントが発生した際、それを知りたい別のオブジェクトへ通知する仕組み」です。

つまりは Observerパターン の実装 で、以下のような「出来事」を 疎結合に伝達 するための仕組みです。

・ボタンが押された
・HPが0になった
・アニメーションが終わった

なぜシグナルを使うのか

Godotにおいて、なぜシグナルを使用するのかはステータスとHUDの実装例を挙げて考えてみるとわかりやすいです。

A) シグナルを使わない場合(密結合)
以下はプレイヤーノードの子にUIノードがあり、プレイヤーのスクリプトからそれを変更するケースです。

# Player.gd
func take_damage(dmg):
	hp -= dmg
	if hp <= 0:
		$UI/GameOverLabel.show()

この実装でも動作には問題ありませんが、以下のようなデメリットがあります。

  • PlayerがUIの存在を知っている
  • UI構成を変えるとPlayerが壊れる
  • 再利用不可

B) シグナルを使う場合(疎結合)
こちらは、プレイヤー用のスクリプトとは別に、UI用のスクリプトが用意されており、シグナルを使って通知を受け取ります。

# Player.gd
signal died

func take_damage(dmg):
	hp -= dmg
	if hp <= 0:
		died.emit()
# UI.gd
func _ready():
	player.died.connect(_on_player_died)

func _on_player_died():
	game_over_label.show()

この用にシグナルを用いた実装は、慣れていないとやや複雑に思えますが、以下のようなメリットがあります。

  • PlayerはUIを一切知らない(影響がない)
  • 複数のオブジェクトが同時に反応可能
  • テスト・再利用・差し替えが容易

おすすめの本 (Godot):

おすすめの本:


ここまでお読みいただき、ありがとうございます。
今回紹介した内容が、皆さんの開発のヒントになれば幸いです。

記事が役に立ったと感じていただけましたら、OFUSE にてご支援いただけますと今後の運営の励みになります。

OFUSEで応援を送る

今後もゲーム制作に関するさまざまな情報や、そこから得られた知見を共有していく予定ですので、引き続き当ブログをよろしくお願いいたします。

  • URLをコピーしました!
目次