Claude Codeが書いたGodotのシーンとノードの読み方【AIでゲーム開発】
Claude Code が書いた Godot の .tscn では、[node で始まる1行が1つのノードで、名前・種類・親・グループはその行に、付いているスクリプトはすぐ下の script の行にありました。シグナルのつながりは .gd の connect の行にありました。この試しでは、グループが見出しの行の外に書かれていてスコアが増えず、1回の直しで5枚目に CLEAR が出るようになりました。
このページの目次
Claude Code に頼んだ文
Godot のエディタを開かずに、Claude Code にファイルを直接書かせました。Godot では、ゲームはシーンに分かれ、1つのシーンはノードの木でできています。できたシーンは、別のシーンの中に置くことができます。Claude Code は、プロジェクトのファイルを読み、ファイルを書き換え、コマンドを動かすツールです。頼んだ文はそのまま次のとおりです(作業フォルダの場所だけが手元のものです)。
Claude CodeにGodotのコイン集めのゲームを頼んだ文
作業フォルダは D:\Claude_Game_Site\drafts\W-142-A\godot-scene-nodes.play\ だけです。このフォルダの外は読まない・書かないでください。
Godot 4 で、2D の小さなゲームのプロジェクトを作ってください。
中身は簡単でいいです:左右キーで動いて上キーでジャンプするプレイヤーが、画面に置いたコイン5枚を集めます。コインに触れるとコインが消えてスコアが1増え、5枚集めたら画面に「CLEAR」と出ます。
シーンは、メインのシーン・プレイヤー・コインを別々のファイルに分けてください。コインを取ったことは、コインからシグナルで知らせてください。
Godot のエディタは開けないので、ファイル(project.godot・.tscn・.gd)を直接書いてください。
できたら、作ったファイルの一覧と、それぞれのシーンにどのノードがあって、どのスクリプトが付いているかを短く返してください。
Claude Code が作り終えるまでの時間は143秒でした。
できたファイルと、Claude Code の説明
できたのは次の7つのファイルです。
- project.godot:最初に動くシーンが scenes/Main.tscn になっている
- scenes/Main.tscn:メインのシーン
- scenes/Player.tscn:プレイヤーのシーン
- scenes/Coin.tscn:コインのシーン
- scripts/Main.gd:スコアを数えて、5枚で CLEAR を出す
- scripts/Player.gd:左右の移動とジャンプ
- scripts/Coin.gd:プレイヤーと重なったらシグナルを出して消える
Claude Code の返事では、Main.tscn の一番上のノード(ルート)は Node2D で Main.gd が付き、その下に Floor・Player・Coin1〜5("coins" グループ)・CanvasLayer があり、CanvasLayer の下に ScoreLabel と ClearLabel がある、と説明されました。Player.tscn のルートは CharacterBody2D、Coin.tscn のルートは Area2D で、コインは collected というシグナルを出してから消える、という説明でした。
.tscn の中でノードを見つける
.tscn はテキストのファイルで、角かっこの見出しの行と、その下の「名前 = 値」の行でできています。見出しの行には、ファイルの外の部品・ファイルの中の部品・ノード・シグナルのつながりの4種類があります。Coin.tscn は次のとおりでした(ファイルの中身そのまま)。
[gd_scene load_steps=2 format=3]
[ext_resource type="Script" path="res://scripts/Coin.gd" id="1"]
[sub_resource type="CircleShape2D" id="CircleShape2D_coin"]
radius = 12.0
[node name="Coin" type="Area2D"]
script = ExtResource("1")
[node name="ColorRect" type="ColorRect" parent="."]
offset_left = -12.0
offset_top = -12.0
offset_right = 12.0
offset_bottom = 12.0
color = Color(1, 0.85, 0.1, 1)
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
shape = SubResource("CircleShape2D_coin")
- ノードは、[node で始まる1行が1つです。name= が名前、type= が種類です。
- parent= が親です。最初の [node の行(ルート)には parent がありません。ルートのすぐ下の子は parent="." です。Main.tscn では、Floor の下の ColorRect が parent="Floor"、ScoreLabel が parent="CanvasLayer" でした。
- 付いているスクリプトは、[node の行のすぐ下の script の行です。かっこの中の "1" は、ファイルの頭にあるファイルの外の部品の行のうち id="1" のものを指します。その行の path= が res://scripts/Coin.gd です。
- 当たりの形のように、ファイルの中で作る部品は、ノードより上の行にあり、ノードの側から SubResource の行で指されます。Coin.tscn では、CollisionShape2D が半径12の CircleShape2D を指していました。
別のシーンを置いたノードを読む
Main.tscn の Player と Coin1〜5 は、別のシーンを置いたノードです。[node の行に type= が無く、instance= がありました。
[ext_resource type="PackedScene" path="res://scenes/Player.tscn" id="2"]
[ext_resource type="PackedScene" path="res://scenes/Coin.tscn" id="3"]
[node name="Player" parent="." instance=ExtResource("2")]
position = Vector2(100, 550)
Coin1〜5 の instance= のかっこの中は "3" で、頭の行の id="3" の res://scenes/Coin.tscn を指します。このため、Coin1 の種類(Area2D)と付いているスクリプト(Coin.gd)は Main.tscn の中には無く、Coin.tscn の [node name="Coin" type="Area2D"] の行と、その下の script の行にあります。Main.tscn の Coin1〜5 の行の下には、置く場所(position)の行がありました。
.gd の中でノードとシグナルを見つける
.gd は GDScript のファイルです。3つとも、1行目の extends が、そのスクリプトが付くノードの種類と同じでした(Coin.gd は Area2D、Player.gd は CharacterBody2D、Main.gd は Node2D)。Coin.gd は次のとおりでした(ファイルの中身そのまま)。
extends Area2D
signal collected
func _ready() -> void:
body_entered.connect(_on_body_entered)
func _on_body_entered(body: Node2D) -> void:
if body.is_in_group("player"):
collected.emit()
queue_free()
- signal collected の行が、コインが出すシグナルの名前です。
- ノードが動き始めたときに呼ばれる関数の中で、ほかの物体が重なったときの知らせを、下の関数につないでいます。
- 重なった相手が "player" グループなら、collected のシグナルを出してから、コインを消します。
Main.gd の7〜14行目は次のとおりでした(ファイルの中身そのまま)。
@onready var score_label: Label = $CanvasLayer/ScoreLabel
@onready var clear_label: Label = $CanvasLayer/ClearLabel
func _ready() -> void:
clear_label.visible = false
_update_score_label()
for coin in get_tree().get_nodes_in_group("coins"):
coin.collected.connect(_on_coin_collected)
- $ のあとの CanvasLayer/ScoreLabel は、Main から見て CanvasLayer の下の ScoreLabel を指す道です。.tscn の parent= の並びと同じです。
- 動き始めたときに "coins" グループのノードを集め、それぞれの collected を、スコアを数える関数につないでいます。スコアを数える関数は、スコアを1増やし、5以上で ClearLabel を見えるようにします。
- 3つの .tscn には [connection で始まる行が1行もありませんでした。このプロジェクトでは、シグナルのつながりはすべて .gd の connect の行で作られています。
説明と実物を1つずつ比べる
Claude Code の返事の説明を、.tscn と .gd の中身と1つずつ比べました。
各シーンのノードの名前・種類・親子と、付いているスクリプト(Main.tscn の Main に Main.gd、Player.tscn の Player に Player.gd、Coin.tscn の Coin に Coin.gd)と、シグナル(Coin.gd の signal collected)は、返事のとおりでした。グループは次のとおりでした。
- "player" グループ:Player.tscn では、[node name="Player" type="CharacterBody2D" groups=["player"]] と、[node の行の中にありました。
- "coins" グループ:返事と違っていました。Main.tscn では、groups=["coins"] が [node の行の中ではなく、その下の行にありました。
groups は、[node の見出しの行の中に書く項目の1つです。見出しの行の下の行は、そのノードのプロパティ(position など)の値です。
Godot を画面なしで動かして確かめる
Godot 4.7.2 を画面なしで動かしました。プロジェクトのファイルは書き換えず、試しの台本はプロジェクトの外に置きました。
- プロジェクトを読み込んで1回だけ回して終える形で動かすと、出たのは Godot の版の1行だけで、エラーも警告もありませんでした。
- 台本で Main.tscn を読み込み、読み込んだあとの様子を書き出しました。"coins" グループのノードは0個、"player" グループは1個でした。Coin1〜5 の collected につながっている先は0本でした。
- 台本から上の操作を押すと、プレイヤーはジャンプして床に戻りました。そのあと右の操作を押し続けると、コインは5枚とも消えましたが、スコアは「Score: 0」のままで、CLEAR は出ませんでした。
"coins" グループが空なので、Main.gd がグループから1つもコインを受け取れず、collected がどこにもつながっていない状態でした。本物のキーボードの矢印キーを押したときの動きは、この試しでは確かめきれませんでした。
Claude Code に直しを頼んだ文
起きたこと・起こし方・調べて分かったこと・望む動きを書いて、別の Claude Code に1回渡しました。渡した文はそのまま次のとおりです。
Claude Codeに直しを頼んだ文
作業フォルダは D:\Claude_Game_Site\drafts\W-142-A\godot-scene-nodes.play\ だけです。このフォルダの外は読まない・書かないでください。
前に作ってもらったコイン集めのプロジェクトで、次のことが起きました。
・起きたこと:プレイヤーがコインに触れるとコインは消えますが、スコアは「Score: 0」のままで、5枚取っても「CLEAR」が出ません。
・起こし方:Godot 4.7.2 を画面なしで動かし、Main.tscn を読み込んで右キーを押し続けたまま、5枚のコインの上を通らせました。読み込みのときにエラーは出ませんでした。
・調べて分かったこと:読み込んだあとで "coins" グループに入っているノードは0個でした。
・望む動き:コインに触れるたびにスコアが1増え、5枚で「CLEAR」が出ること。
直したら、どのファイルの何行目をどう変えたかと、.tscn の中でノードの名前・種類・親・グループ・スクリプトがそれぞれどこに書かれているかを、Main.tscn の Coin1 を例に短く返してください。Claude Code が直し終えるまでの時間は51秒でした。
直したあとの結果
Claude Code は、Main.tscn の Coin1〜Coin5 の5か所で、groups=["coins"] を [node の行の中に移しました。直したあとの Coin1 は次のとおりです。
[node name="Coin1" parent="." groups=["coins"] instance=ExtResource("3")]
position = Vector2(250, 560)
直したあとを、Godot を画面なしで動かして数え直しました。
- 読み込みでは、エラーも警告も出ませんでした。
- "coins" グループのノードは5個になり、Coin1〜5 の collected はそれぞれ1本ずつ、スコアを数える関数につながっていました。
- 台本から右の操作を押し続けると、コインに触れるたびにスコアが1ずつ増えて「Score: 5」になり、CLEAR が見えるようになりました。
直す前に groups が次の行にあったときに、エラーも警告も出ずにグループに入らなかったことは、前の節で動かして見たとおりです。Claude Code は、その理由を「見出しの行の外に書くと groups という名前のプロパティへの代入として扱われ、Area2D にも Coin.gd にもそのプロパティが無いので、黙って無視された」と説明しました。この試しで確かめたのは、読み込んだ Coin1 のプロパティの一覧に groups という名前が無いことまでです。
情報源
- TSCN file format(Godot Engine の公式ドキュメント)https://docs.godotengine.org/en/stable/engine_details/file_formats/tscn.html確認日 2026-09-24
- Nodes and Scenes(Godot Engine の公式ドキュメント)https://docs.godotengine.org/en/stable/getting_started/step_by_step/nodes_and_scenes.html確認日 2026-09-24
- Creating instances(Godot Engine の公式ドキュメント)https://docs.godotengine.org/en/stable/getting_started/step_by_step/instancing.html確認日 2026-09-24
- Using signals(Godot Engine の公式ドキュメント)https://docs.godotengine.org/en/stable/getting_started/step_by_step/signals.html確認日 2026-09-24
- Groups(Godot Engine の公式ドキュメント)https://docs.godotengine.org/en/stable/tutorials/scripting/groups.html確認日 2026-09-24
- Nodes and scene instances(Godot Engine の公式ドキュメント)https://docs.godotengine.org/en/stable/tutorials/scripting/nodes_and_scene_instances.html確認日 2026-09-24
- Command line tutorial(Godot Engine の公式ドキュメント)https://docs.godotengine.org/en/stable/tutorials/editor/command_line_tutorial.html確認日 2026-09-24
- Overview(Claude Code の公式ドキュメント)https://code.claude.com/docs/en/overview確認日 2026-09-24
