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

ziva-sh/godot-4-api-pitfalls

Godot 3のAPIやGDScript構文をGodot 4プロジェクトで使わないように修正します。KinematicBody2D、move_and_slide(velocity)、export、onready、setget、yield、string connect()、instance()、rand_range、Tweenノード、File、change_scene、Spatial、rect_*プロパティ、Pool*Array、OS時間関数、旧TileMap APIなどを検出・変換します。Godot 4.x向けのGDScript作成、レビュー、移植の際や、「not declared」「not found in base」「was removed in Godot 4」「is not present」といったエラーが出たときに使用します。

godot-4-api-pitfalls とは?

このスキルは、AIアシスタントがGodot 4プロジェクトでGodot 3のAPIやGDScript構文を誤って生成する問題を解決します。多くのチュートリアルやフォーラムの回答、モデルの学習データはGodot 3に基づいているため、Godot 4ではクラス名、メソッド、プロパティの変更やGDScript構文の変更により、コードがパースエラーとなったり、実行時にのみエラーとなる場合があります。スキルは、主要な非互換項目を包括的な変換表として提供し、KinematicBody2D→CharacterBody2D、move_and_slide()の新しい使い方、@exportや@onreadyなどの新しいアノテーション、await/シグナルシステム、Tween API、ファイルアクセス、TileMapからTileMapLayerへの移行など、あらゆる変更をカバーします。また、パーサーが検出できない実行時エラーや動作変更についても解説し、安全なコードへの変換を支援します。

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

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

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

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

ドキュメント

Godot 4 API の落とし穴

チュートリアル、フォーラムの回答、モデルの学習データに含まれるGDScriptのほとんどはGodot 3用です。Godot 4ではクラス、メソッド、プロパティの名称が変更され、GDScript構文も変更されました。一部のGodot 3コードはパースに失敗し、また別の一部はパースは通っても実行時にのみ壊れます。コードを書く前に、バージョンを確認してください。project.godot に config/features=PackedStringArray("4.7", ...) のような行があります。

変換表

Godot 3(Godot 4では誤り)Godot 4
KinematicBody2D, KinematicBodyCharacterBody2D, CharacterBody3D
velocity = move_and_slide(velocity, Vector2.UP)velocity プロパティを設定してから、move_and_slide() を引数なしで呼び出します。up_direction や floor_snap_length はプロパティです
export var x = 1, export(int, 0, 10) var x@export var x := 1, @export_range(0, 10) var x: int
export(String, FILE, "*.json") var path@export_file("*.json") var path: String
export(Array, int) var a@export var a: Array[int]
onready var, tool@onready var, @tool
var hp setget set_hp, get_hpvar hp: int: set = set_hp, get = get_hp、またはインラインの set(value): ブロック
yield(obj, "signal_name")await obj.signal_name
yield(get_tree().create_timer(1.0), "timeout")await get_tree().create_timer(1.0).timeout
yield(get_tree(), "idle_frame")await get_tree().process_frame
connect("pressed", self, "_on_pressed", [arg])pressed.connect(_on_pressed.bind(arg))
emit_signal("died")died.emit()(文字列形式も機能しますが、タイプミスは実行時にしか見つかりません)
scene.instance()scene.instantiate()
get_tree().change_scene(path), change_scene_to(packed)change_scene_to_file(path), change_scene_to_packed(packed)
rand_range(a, b)randf_range(a, b) または randi_range(a, b)
stepify, deg2rad, rad2deg, range_lerp, str2varsnapped, deg_to_rad, rad_to_deg, remap, str_to_var
Tween ノード: $Tween.interpolate_property(...), start()var tween := create_tween()、そして tween.tween_property(node, "property", final_value, duration)
File.new(), file.open(path, File.READ)FileAccess.open(path, FileAccess.READ)(失敗時は null を返します。FileAccess.get_open_error() を参照)
Directory.new()DirAccess.open(path)
to_json(v), parse_json(s)JSON.stringify(v), JSON.parse_string(s)
OS.get_ticks_msec(), OS.get_unix_time(), OS.get_datetime()Time.get_ticks_msec(), Time.get_unix_time_from_system(), Time.get_datetime_dict_from_system()
OS.window_fullscreen = true, OS.get_screen_size()DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN), DisplayServer.screen_get_size()
OS.set_window_title("Game")get_window().title = "Game"
Spatial, translationNode3D, position
extends Reference, Transform, Quatextends RefCounted, Transform3D, Quaternion
pause_mode = PAUSE_MODE_PROCESSprocess_mode = PROCESS_MODE_ALWAYS
Sprite, AnimatedSprite, Position2D, Particles2D, TextureProgressSprite2D, AnimatedSprite2D, Marker2D, GPUParticles2D, TextureProgressBar
rect_position, rect_size, rect_min_sizeposition, size, custom_minimum_size
margin_left(Control)offset_left
Label.align = Label.ALIGN_CENTERhorizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
add_color_override, add_font_override, add_stylebox_override, add_constant_overrideadd_theme_color_override, add_theme_font_override, add_theme_stylebox_override, add_theme_constant_override
Color.red, Color.whiteColor.RED, Color.WHITE
PoolStringArray, PoolVector2Array, PoolIntArray, PoolRealArrayPackedStringArray, PackedVector2Array, PackedInt32Array, PackedFloat32Array
update()(CanvasItem の再描画)queue_redraw()
TileMap.set_cellv(pos, id), world_to_mapTileMapLayer.set_cell(coords, source_id, atlas_coords), local_to_map(godot-tilemaplayer スキルを参照)
BUTTON_LEFT, BUTTON_WHEEL_UPMOUSE_BUTTON_LEFT, MOUSE_BUTTON_WHEEL_UP
event.scancode, event.controlevent.keycode(または physical_keycode), event.ctrl_pressed
array.empty(), array.remove(i), array.invert()is_empty(), remove_at(i), reverse()
set_collision_layer_bit(0, true)(0ベースのビット)set_collision_layer_value(1, true)(1ベースのレイヤー番号)
space_state.intersect_ray(from, to)space_state.intersect_ray(PhysicsRayQueryParameters2D.create(from, to))
RayCast2D.cast_totarget_position
get_tree().set_input_as_handled()get_viewport().set_input_as_handled()
remote func, remotesync func, puppet func, is_network_master()@rpc("any_peer") func, @rpc("any_peer", "call_local") func, @rpc func(権限者のみ呼び出し可能), is_multiplayer_authority()。master func の直接の同等物はありません。@rpc("any_peer") を使用し、multiplayer.get_remote_sender_id() で確認してください
Engine.editor_hint, filenameEngine.is_editor_hint(), scene_file_path
RectangleShape2D.extents(半分のサイズ)size(全体のサイズ、つまり古い値の2倍)
ResourceSaver.save(path, resource)ResourceSaver.save(resource, path)

あまり一般的でない名前変更(3D、XR、ナビゲーション、シェーダー、スレッド)については、references/renames.md を参照してください。

変換前と変換後

キャラクターコントローラ:

extends KinematicBody2D

export var speed = 200
var velocity = Vector2()

func _physics_process(delta):
	velocity.x = Input.get_axis("ui_left", "ui_right") * speed
	velocity = move_and_slide(velocity, Vector2.UP)
extends CharacterBody2D

@export var speed := 200.0
@export var jump_velocity := -400.0


func _physics_process(delta: float) -> void:
	if not is_on_floor():
		velocity += get_gravity() * delta
	if Input.is_action_just_pressed("ui_accept") and is_on_floor():
		velocity.y = jump_velocity
	velocity.x = Input.get_axis("ui_left", "ui_right") * speed
	move_and_slide()

プロパティ、シグナル、タイマー、トゥイーン:

tool
extends Node2D

export(int, 0, 100) var health = 100 setget set_health
onready var button = $Button

func _ready():
	button.connect("pressed", self, "_on_button_pressed")

func set_health(value):
	health = clamp(value, 0, 100)
	update()

func _on_button_pressed():
	$Tween.interpolate_property(self, "modulate:a", 1.0, 0.0, 0.5)
	$Tween.start()
	yield($Tween, "tween_all_completed")
	queue_free()
@tool
extends Node2D

@export_range(0, 100) var health: int = 100:
	set(value):
		health = clampi(value, 0, 100)
		queue_redraw()

@onready var button: Button = $Button


func _ready() -> void:
	button.pressed.connect(_on_button_pressed)


func _on_button_pressed() -> void:
	var tween := create_tween()
	tween.tween_property(self, "modulate:a", 0.0, 0.5)
	await tween.finished
	queue_free()

ファイル、時間、ランダム、シーン:

extends Node

func save_score(score):
	var file = File.new()
	file.open("user://save.json", File.WRITE)
	file.store_string(to_json({"score": score, "time": OS.get_unix_time()}))
	file.close()

func spawn(scene):
	var enemy = scene.instance()
	enemy.position = Vector2(rand_range(0, 100), 0)
	add_child(enemy)
extends Node

@export var enemy_scene: PackedScene


func save_score(score: int) -> void:
	var file := FileAccess.open("user://save.json", FileAccess.WRITE)
	if file == null:
		push_error("Cannot open save file: %s" % error_string(FileAccess.get_open_error()))
		return
	file.store_string(JSON.stringify({"score": score, "time": Time.get_unix_time_from_system()}))


func spawn() -> void:
	var enemy := enemy_scene.instantiate() as Node2D
	enemy.position = Vector2(randf_range(0.0, 100.0), 0.0)
	add_child(enemy)


func go_to_menu() -> void:
	get_tree().change_scene_to_file("res://menu.tscn")

パーサーが検出できないもの

godot --check-only は、未知のメンバーを、レシーバーが self、組み込み型(Array、Vector2、Color)、または静的呼び出しされるクラス名(OS.get_unix_time())の場合にのみエラーとして報告します。引数の数や型の誤りもエラーです。var shape := RectangleShape2D.new() のような型付きのオブジェクトであっても、メンバーが欠落している場合は「サブタイプに存在する可能性がある」と見なされ、デフォルト設定ではパースが通ります。以下のGodot 3の行はすべて、Godot 4.7.2で --check-only をパスし、実行時にのみ失敗します。

  • PackedScene に対する scene.instance()、get_tree().change_scene(path)、get_tree().set_input_as_handled()
  • RectangleShape2D に対する shape.extents、$Panel.rect_size
  • InputEvent に対する event.scancode または event.control

チェック中にこれらを拒否させるには、project.godot の隣に一時的な override.cfg に以下の行を置き(Godotは project.godot の上からこれを読み込みます。--check-only 時も同様です)、その後削除してください。プロジェクトに既に override.cfg がある場合は、代わりに追加して元に戻してください。2 はエラーを意味します:

[debug]
gdscript/warnings/unsafe_method_access=2
gdscript/warnings/unsafe_property_access=2

ユーザーの project.godot にこれらを残さないでください。要求された場合を除きます。エラー設定では、body.take_damage(1) や $Sprite.play() のような型指定のない呼び出しはすべてパースエラーとなり、ゲームは終了コード0で起動し、「Failed to load script」とだけ出力します。型指定されたコードはパスするので、型指定された参照を優先してください。@onready var panel: Panel = $Panel、そして key.keycode を読み取る前に var key := event as InputEventKey を使用します。

どのパーサーも検出できない動作の変更:

  • _ready() などのライフサイクルメソッドは、デフォルトで親クラスの実装を暗黙的に呼び出さなくなりました。継承されたスクリプトで必要な場合は、super() を呼び出してください。
  • Array.slice(begin, end) は end を除外します。
  • Camera2D.zoom は反転しています。値が大きいほどズームインします。
  • String.right(n) は最後の n 文字を返します。
  • randomize() は起動時に自動的に実行されます。再現可能なランダム性を得るには seed() を設定します。
  • call_group() は即時実行です。古い遅延動作には call_group_flags(SceneTree.GROUP_CALL_DEFERRED, ...) を使用します。
  • AnimatedSprite2D.playing は削除されました。play() を呼び出します。
  • TileMap はまだ存在しますが、非推奨です。新しいコードでは、レイヤーごとに1つの TileMapLayer ノードを使用します。

セルフチェック

  1. 作成または変更したスクリプトからGodot 3の名称を検索します(GNU grep。必要に応じて -P を追加するか、他のgrepに適応させてください):

    grep -rnE --include='*.gd' \
      -e '\b(KinematicBody2D|KinematicBody|Spatial|Position2D|Particles2D|TextureProgress)\b' \
      -e '\b(yield|setget|rand_range|stepify|deg2rad|rad2deg|range_lerp|to_json|parse_json|funcref)\b' \
      -e '\b(idle_frame|pause_mode|Reference|Quat)\b|\bPAUSE_MODE_' \
      -e '^(export|onready|tool)\b|^(remote|master|puppet)(sync)? func' \
      -e '\.instance\(|change_scene(_to)?\(|\b(File|Directory)\.new\(|OS\.(get_ticks|get_unix_time|get_datetime|window_)' \
      -e '\brect_[a-z_]+\b|(^|[^"])\bmargin_(left|right|top|bottom)\b|add_(color|font|stylebox|constant|icon)_override' \
      -e '\bPool[A-Za-z0-9]+Array\b|\bBUTTON_(LEFT|RIGHT|MIDDLE|WHEEL)|\.scancode\b|set_cellv|world_to_map|map_to_world' \
      -e 'connect\("[^"]+", *self|interpolate_property|\bextends +Sprite *$' .
    

    各一致を上記の表で書き換えてください。MarginContainer の引用符で囲まれた "margin_left" テーマ定数はGodot 4の名称であり、一致しません。一致がないことはコードがGodot 4であることを証明しません。リストは一般的なサブセットだからです。

  2. プロジェクトルートから変更した各スクリプトをパースします: godot --headless --path . --check-only --script res://path/to/script.gd。終了コードだけでなく、出力を読んでください。上記の一時的な override.cfg を使用すると、型付きオブジェクトの名前変更されたメンバーもここで失敗します。

  3. そのスクリプトを使用するシーンを実行し、その出力を読んでください。実行時エラーは終了コードを変更しないからです。godot-verifyスキルにコマンドがあります。

Individual skills in this repo

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

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-scene-organization

Structures Godot 4 projects so scenes stay reusable and references do not break - when to make a scene, a script or a Resource, instancing with @export PackedScene, preload and load, @onready and %UniqueName node access, _ready order, groups, autoloads, class_name, and resource UIDs with the .uid files added in Godot 4.4, including how to move or rename files safely. Use when creating new scenes or scripts, deciding how nodes find each other, adding global state or an event bus, moving or renami

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

関連スキル