はじめてのGodot 第4回: 隕石を作ろう — シーンを部品として作る


前回までで宇宙船は完成しました。今回は敵役の隕石を作ります。ポイントは、隕石をメインシーンの中に直接作るのではなく、独立したシーン(部品)として作ることです。

今回のゴール

隕石が画面の上から下へまっすぐ落ちていく様子

隕石シーンが単体で動く: まっすぐ落ちて、画面外に出たら自動で消える。

なぜ別シーンにするのか

第1回で「シーン=部品のまとまり」と説明しました。隕石を独立したシーンにしておくと、次回「この部品を毎秒コピーして量産する」ということができるようになります。逆にメインシーンに直接作ってしまうと、量産できません。

繰り返し登場するものは、独立したシーンにする」 — これがGodotの設計の基本ルールです。

隕石シーンを作る

メニューの「シーン」→「新規シーン」で、まっさらなシーンを開きます。

  1. 「その他のノード」から Area2D を選んで作成し、名前を Meteor に変更
  2. Meteor の子に Sprite2D を追加し、Textureに meteorBrown_big1.png を設定
  3. Meteor の子に CollisionShape2D を追加
  4. Meteor の子に VisibleOnScreenNotifier2D を追加
  5. Ctrl+S(MacはCmd+S)で保存(meteor.tscn)

それぞれのノードの役割

  • Area2D(ルート): 「何かと重なったことを検知する」ノード。当たり判定の本体です。第6回で宇宙船との衝突に使います
  • CollisionShape2D: Area2Dの「判定の形」を決めるノード。シーンドックに⚠マークが出ているはずです — 形がまだ設定されていないからです。インスペクタの「Shape」で「新規CircleShape2D」を選び、ビューポート上で円のハンドルをドラッグして、隕石の絵より少し小さめに合わせてください(小さめにすると「かすったのにミスった」という理不尽感が減ります)
  • VisibleOnScreenNotifier2D: 「画面に映っているか」を教えてくれるノード。ビューポート上で四角形を隕石の絵と同じくらいの大きさに広げておいてください

落ちるスクリプトを書く

Meteor(ルート)にスクリプトをアタッチします(meteor.gd)。

extends Area2D

var speed = 300.0

func _process(delta):
	position.y += speed * delta

前回学んだ座標系を思い出してください。yを増やす=下に動くです。delta を掛けるのも前回どおり。

画面外に出たら自分を消す

落ちた隕石を放置すると、画面の下で見えないまま永遠に落ち続け、数が増えるほどゲームが重くなります。用済みの部品は自分で消すのが作法です。

ここで、はじめて「シグナル」を使います。シグナルは「何かが起きたよ」というノードからの通知です。

  1. シーンドックで VisibleOnScreenNotifier2D を選択
  2. インスペクタの隣の「シグナル」タブを開く(そのノードが発するシグナルの一覧が出ます)
  3. screen_exited()(画面から出たとき)をダブルクリック
  4. 接続先に Meteor を選んで「接続」

すると meteor.gd に関数が自動で生えます。中身を1行書きます。

func _on_visible_on_screen_notifier_2d_screen_exited():
	queue_free()

queue_free() は「このノードを削除する」命令です。これで「画面から出たら、自分を消す」が完成しました。

単体でテストする

シーンを部品として作る利点がもうひとつ — 部品単体でテストできることです。

  1. ビューポート上で Meteor を画面上部の中央あたり((240, 50) など)にドラッグ
  2. F6(MacはCmd+R)を押す(F5/Cmd+B がメインシーンの実行、F6/Cmd+R は今開いているシーンの実行です)
  3. 隕石が落ちて、画面外に消えれば成功

確認できたら、Meteor のPositionを (0, 0)戻しておいてください。出現位置は次回コードで決めるためです。

つまずきポイント

  • ⚠マークが消えない: CollisionShape2Dの「Shape」が空のままです。「新規CircleShape2D」を設定してください
  • F6(MacはCmd+R)で実行しても何も見えない: 隕石のPositionが (0,0)(画面左上の角)のままかもしれません。テスト中だけ画面内に動かしてください
  • 消えたかどうか分からない: 実行ウィンドウのまま放置せず、エディタ下部の「リモート」タブを見ると、実行中のノード一覧からMeteorが消える瞬間が確認できます(余裕があれば)

今回学んだこと

  • 繰り返し登場するものは独立したシーンにする(次回、量産できる)
  • Area2D + CollisionShape2D が当たり判定のセット
  • シグナルは「何かが起きた」というノードからの通知。エディタの「シグナル」タブで接続する
  • queue_free() で用済みのノードを削除し、ゲームが重くなるのを防ぐ
  • F6(MacはCmd+R)で現在のシーンを単体実行してテストできる

次回予告

第5回では、この隕石部品を毎秒ランダムな場所に量産します。一気に「ゲームらしさ」が出る、気持ちのいい回です。

第5回: 隕石をランダムに降らせよう — タイマーとインスタンス化