Communityコーディング&開発github.com

ziva-sh/godot-scene-organization

Godot 4プロジェクトのシーン構成を整理し、再利用性を高め、参照を壊さないためのルールとテクニックを提供します。

godot-scene-organization とは?

このスキルは、Godot 4プロジェクトにおけるシーン、スクリプト、リソースの適切な使い分けと、シーン間の参照を安全に保つためのベストプラクティスを提供します。シーンを作成・編集する際に、@export PackedScene、preload、loadの使い分け、@onready変数と%UniqueNameを用いたノード参照の方法、_readyの実行順序、グループ、オートロード、class_name、そしてGodot 4.4で導入された.uidファイルを使ったリソースUIDの管理方法をカバーします。また、ファイルの移動やリネームを安全に行うための手順や、よくあるミスの回避策も含まれており、特にClaude CodeやCursorなどのAIエージェントがGodotプロジェクトを編集する際に、参照切れを防ぎながら効率的にコードを生成・修正できるように設計されています。

対応~Claude Code~Codex CLI~Cursor
Part ofMobile
npx skills add https://github.com/ziva-sh/godot-skills/tree/HEAD/skills/godot-scene-organization

Installed? Explore more コーディング&開発 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

Godot 4におけるシーン構成

シーン、スクリプト、リソース

  • シーン (.tscn): ノードとそのリソースからなる再利用可能なツリー。プレイヤー、敵、アイテム、UIパネル、レベルなど。複数回配置するものや単独で実行したいもの (F6) はシーンにします。
  • スクリプト (.gd): 1つのノードにアタッチする動作。制御するシーンのルートノードにアタッチし、親ノードから内部にアクセスしようとするものにはアタッチしません。
  • リソーススクリプト (extends Resourceとclass_nameを使う): ノードを持たないデータ。アイテムのステータス、ウェーブ定義、セーブデータなど。インスペクタで編集し、.tresとして保存します。

シーンは単独で実行しても動作するようにします。外部から何か (ターゲット、スポーン親など) が必要な場合は、get_parent()チェーンを使う代わりに@exportまたはシグナルで公開します。

シーンのインスタンス化

extends Node2D

@export var enemy_scene: PackedScene
@export var spawn_parent: Node2D


func spawn_enemy(at: Vector2) -> void:
	var enemy := enemy_scene.instantiate() as Node2D
	enemy.position = at
	spawn_parent.add_child(enemy)


func load_level(path: String) -> void:
	var packed := load(path) as PackedScene
	if packed == null:
		push_error("Level not found: " + path)
		return
	get_tree().change_scene_to_packed(packed)
  • @export var x: PackedScene はインスペクタで設定され、シーンが参照を保存するためファイル移動後も有効です。
  • const BULLET := preload("res://bullet.tscn") はパース時に解決されます。ファイルがないとパースエラーになります (Preload file "res://bullet.tscn" does not exist.)。固定アセットに適しています。
  • load() は実行時に解決され、パスが間違っているとnullとエラーを返します。実行時にパスを構築する場合に使います。
  • instantiate() (Godot 3のinstance()ではない) はNodeを返すので、必要な型にキャストします。インスタンスはqueue_free()で解放します。

ノードの検索

extends Control

@onready var title: Label = %Title
@onready var start_button: Button = %StartButton
@onready var music: AudioStreamPlayer = $Music
@onready var optional_hint: Label = get_node_or_null("Hint")


func _ready() -> void:
	title.text = "Main menu"
	start_button.grab_focus()
	if optional_hint:
		optional_hint.visible = false
	music.play()
  • $Path は get_node("Path") と同義で、このノードからの相対パスです。ノードがないとエラーになります。省略可能なノードにはget_node_or_null()を使います。
  • %Name は、同じシーン内で「ユニーク名としてアクセス」とマークされたノード (Sceneドックで右クリック) にどこからでもアクセスでき、シーン内でのリペアレント後も有効です。インスタンス化された子シーンには到達しません。その場合は $Child/%Name または、インスタンス自体がユニークなら %Child/%Name を使います。
  • @onready 変数は _ready() の直前に割り当てられます。_init() や _enter_tree() では null です。
  • _ready() は子ノードが親ノードより先に実行されるため、親の _ready() は子ノードを使用できますが、子ノードの _ready() は親の準備ができていることに依存してはいけません。
  • @onready 変数には型 (: Label) を指定して、パーサーがメンバー名をチェックできるようにします。型指定なしのパスで $Label.txt と書くと実行時までエラーは検出されません。

グループ

グループはシーンをまたいでノードにタグを付けます。Nodeドック (Groupsタブ) またはコードで追加し、ツリーをクエリします:

extends Node


func _ready() -> void:
	add_to_group("enemies")


func alert_all_enemies() -> void:
	get_tree().call_group("enemies", "set_alerted", true)
	for enemy in get_tree().get_nodes_in_group("enemies"):
		print(enemy.name)
	var player := get_tree().get_first_node_in_group("player") as Node2D
	if player:
		print("Player at ", player.global_position)

call_group() はGodot 4では即座に呼び出されます。遅延させるには get_tree().call_group_flags(SceneTree.GROUP_CALL_DEFERRED, ...) を使います。

オートロード

オートロードはメインシーンの前に作成され、シーン変更後も保持されるノードです。1つのシーンを超えて存続する状態 (設定、セーブデータ、シーンスイッチャー) や、シグナルのみのイベントバスに使います。プロジェクト設定 > Globals > Autoload で登録します。project.godot には次のように記述されます:

[autoload]

Events="*res://autoload/events.gd"

* は「有効」がチェックされていることを意味し、スクリプトから名前を直接使用できます (Events.player_died.emit())。オートロードを free() や queue_free() してはいけません。オートロードは少数に留めてください。1つのレベルに属するものは、そのレベルのシーンに配置すべきです。

ツールに関する注意: godot --check-only --script はオートロードをロードしないため、オートロード名を使用するスクリプトは、実際には動作しても Identifier not found: Events と報告します。そのようなスクリプトはシーンを実行して検証してください (godot-verifyスキルを参照)。

class_name

class_name Player はグローバル型を登録するため、他のスクリプトで var player: Player と書いてメンバーチェックができるようになります。エディタは .godot/ にグローバルクラスキャッシュを保持します。エディタ外で class_name を追加した場合は、それを使用するスクリプトをチェックする前にエディタを開くか、godot --headless --path . --import を実行してください。

UID、.uidファイル、ファイル移動

Godot 4はパスだけでなくUIDでもリソースを参照します。シーンとリソースは独自のUIDをファイルヘッダーに、インポートされたアセットは .import ファイルに保存し、Godot 4.4以降ではスクリプトとシェーダーはコンパニオンファイル (player.gd.uid、water.gdshader.uid) を取得します。エディタで保存された参照は次のようになります:

[ext_resource type="Script" uid="uid://dxxoiuob4eoum" path="res://game_manager.gd" id="1_feb5d"]

ルール:

  • *.uid ファイルはバージョン管理にコミットしてください。.gitignore に追加しないでください。
  • 可能な場合はGodotのファイルシステムドックでファイルを移動・リネームしてください。参照が更新されます。
  • Godot外部 (シェル、IDE、エージェント) でスクリプトやシェーダーを移動する場合は、その .uid ファイルも一緒に移動し、その後エディタを開くか godot --headless --path . --import を実行してUIDキャッシュが新しいパスを学習するようにしてください。そのスキャンが行われるまでは古いパスが使用され、ロードが失敗します。
  • .uid ファイルを置き去りにすると、Godotは移動したスクリプトに新しいUIDを生成し、古いUIDを参照していたシーンは古いパスにフォールバックします: WARNING: ... invalid UID: uid://... - using text path instead: res://old/path.gd、その後 ERROR: ... referenced non-existent resource。
  • .tscn を手書きする場合は、uid= の値を独自に作成しないでください。属性を省略し、正しい path を使用してください。エディタが次にシーンを保存するときにUIDを追加します。
  • 手書きのGodot 4シーンは [gd_scene format=3] で始まり、リソースを文字列IDで参照します: [ext_resource type="Script" path="res://main.gd" id="1_main"]、そしてノード上で script = ExtResource("1_main") とします。子ノードには parent="." またはルートからのパスが必要です。Godot 4.7ではノードに unique_id= も書き込まれますが、手書きの場合は省略します。
  • load("uid://...") と preload("uid://...") はUID文字列を受け入れます。ファイルシステムドックのコンテキストメニューからUIDをコピーできます。ResourceUID.id_to_text(ResourceLoader.get_resource_uid(path)) でコードから取得することもできます。

よくあるミス

  • get_parent().get_parent() や絶対パス /root/Main/Player で上にアクセスする。代わりに参照をエクスポートするか、グループを使うか、シグナルを発行します。
  • _init() やノードがツリーに入る前にノードを使用する。
  • 多くのスクリプトでシーンへの res:// パスをハードコーディングし、PackedScene をエクスポートしない。
  • .uid ファイルなしで .gd ファイルを移動する、または git で *.uid を無視する。
  • 便利だからといって何でもオートロードにする。

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

ziva-sh/godot-4-api-pitfalls

Fixes Godot 3 APIs and GDScript syntax that AI assistants write into Godot 4 projects, such as KinematicBody2D, move_and_slide(velocity), export, onready, setget, yield, string connect(), instance(), rand_range, the Tween node, File, change_scene, Spatial, rect_* properties, Pool*Array, OS time functions and the old TileMap API. Use when writing, reviewing or porting GDScript for Godot 4.x, when a script fails with "not declared", "not found in base", "was removed in Godot 4" or "is not present

ziva-sh/godot-control-layout

Builds Godot 4 Control UIs that resize instead of clipping or overlapping - containers versus anchors, anchor presets from code, size flags, custom_minimum_size, MarginContainer margins, Label wrapping, mouse_filter, CanvasLayer HUDs, Godot 4 theme override names (add_theme_color_override and friends) and the display/window/stretch settings for multiple resolutions. Use when creating or fixing menus, HUDs, dialogs and inventory screens, when UI elements are cut off, zero-sized, overlapping, igno

ziva-sh/godot-signals

Godot 4 signal patterns and their failure modes - declaring typed signals, emit(), connect() and disconnect() with Callables, bind() and unbind(), lambdas, CONNECT_ONE_SHOT and CONNECT_DEFERRED, await on signals and timers, editor-made connections stored in .tscn files, and the call down, signal up rule. Use when wiring UI buttons, timers, Area2D or body events and custom game events, when replacing Godot 3 connect("signal", self, "method") or yield code, or when debugging "already connected", "

ziva-sh/godot-tilemaplayer

Correct Godot 4.3+ TileMapLayer code - set_cell(coords, source_id, atlas_coords), reading cells and custom data, erasing, coordinate conversion, terrains, tile collision through TileSet physics layers, finding the tile a body hit, and migrating from the deprecated TileMap node and its layer-index API. Use when placing, reading or erasing tiles from GDScript, building a TileSet in code, generating levels procedurally, handling tile collisions, or porting TileMap code from Godot 3 or Godot 4.0 to

関連スキル