godot-2d-movement について
Godot 4.7でCharacterBody2Dを使った2Dキャラクター移動を実装するためのスキルです。プラットフォーマーや見下ろし型の制御、衝突結果の確認、よくある問題を扱います。
主な機能
- 01CharacterBody2Dの移動設定
- 02プラットフォーマーの重力とジャンプ
- 03見下ろし型の8方向移動
- 04スライド衝突と床判定
- 05コヨーテタイムの実装例
- 06Godot 4.xの移動時の注意点
活用シーン
- 01プラットフォーマーの操作キャラクター実装
- 02見下ろし型キャラクターの作成
- 03床や衝突の問題の調査
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ gamedev-skills/ awesome-gamedev-agent-skills --skill godot-2d-movementインストール後、Claude Code で/godot-2d-movementを入力して読み込まれたか確認します。
同梱ファイルreferences/controller-recipes.md
詳細
Godot 2D Movement(4.x)
CharacterBody2D と引数なしの move_and_slide() を使って、反応のよい 2D キャラクターコントローラーを作成します。対象は Godot 4.7 です。
使用する場面
- プラットフォーマー(重力+ジャンプ)やトップダウン(自由な 8 方向移動)、坂道の歩行、壁・床の検出など、移動して衝突する 2D プレイヤー/敵をスクリプトで動かす場合に使用します。
move_and_slide()が「何もしない」、キャラクターが床をすり抜ける、またはis_on_floor()が常に false になる場合に使用します。
使用しない場面: 動的剛体、エリア、レイキャスト、衝突レイヤー → godot-physics、タイルベースのレベル → godot-tilemap、プラットフォーマーゲーム全体のテンプレート → platformer ジャンルスキル、エンジンに依存しない操作感の調整 → physics-tuning。
基本的なワークフロー
CollisionShape2Dを子に持つCharacterBody2Dを使用します。 スクリプトで制御するため、単独では落下したり、力に反応したりしません。velocityプロパティを設定してから、move_and_slide()を呼び出します(4.x では引数を指定しません)。このメソッドはvelocityを読み取り、ボディを移動させ、表面に沿って滑らせ、実際の動きを反映するようvelocityを更新します。_physics_process(delta)内で実行します。move_and_slide()は物理ステップの delta を内部で使用するため、自分でvelocityにdeltaを掛けないでください。- プラットフォーマー: 毎ティック
velocity.yに重力を加え、is_on_floor()が true のときにvelocity.yを負の値に設定してジャンプします。 - トップダウン: 入力から方向を作り、速度を掛けます。
motion_mode = MOTION_MODE_FLOATINGを設定して、「床/壁」の区別がない状態にします。 - 呼び出し後に
is_on_floor()、is_on_wall()、get_wall_normal()、get_slide_collision(i)で結果を読み取ります。
パターン
1. プラットフォーマーコントローラー(重力、ジャンプ、坂道)
extends CharacterBody2D
@export var speed := 200.0
@export var jump_velocity := -400.0
@export var gravity := 1200.0 # pixels/sec^2 (tune to taste)
func _physics_process(delta: float) -> void:
# Apply gravity while airborne.
if not is_on_floor():
velocity.y += gravity * delta
# Jump only when grounded (Input action set in Project Settings > Input Map).
if Input.is_action_just_pressed("jump") and is_on_floor():
velocity.y = jump_velocity
# Horizontal input: -1, 0, or 1.
var dir := Input.get_axis("move_left", "move_right")
if dir != 0.0:
velocity.x = dir * speed
else:
velocity.x = move_toward(velocity.x, 0.0, speed) # decelerate to a stop
move_and_slide() # 4.x: no arguments; uses and updates `velocity`
2. トップダウン 8 方向移動
extends CharacterBody2D
@export var speed := 220.0
func _ready() -> void:
motion_mode = CharacterBody2D.MOTION_MODE_FLOATING # no floor/ceiling concept
func _physics_process(_delta: float) -> void:
# get_vector returns a normalized-ish Vector2 from four input actions.
var input := Input.get_vector("move_left", "move_right", "move_up", "move_down")
velocity = input * speed
move_and_slide()
3. 移動後のスライド衝突の読み取り
func _physics_process(delta: float) -> void:
# ... set velocity ...
move_and_slide()
for i in get_slide_collision_count():
var c := get_slide_collision(i)
var other := c.get_collider()
if other and other.is_in_group("enemies"):
take_damage(1) # touched an enemy while moving
4. コヨーテタイム(足場から出た直後でもジャンプできる猶予時間)
@export var coyote_time := 0.1
var _coyote := 0.0
func _physics_process(delta: float) -> void:
if not is_on_floor():
velocity.y += gravity * delta
_coyote -= delta
else:
_coyote = coyote_time
if Input.is_action_just_pressed("jump") and _coyote > 0.0:
velocity.y = jump_velocity
_coyote = 0.0
# ... horizontal input + move_and_slide() ...
注意点
- 3.x のシグネチャーは廃止されています。 新しい速度を返す
move_and_slide(velocity)は削除されました。4.x ではvelocityプロパティを設定し、引数なしでmove_and_slide()を呼び出します。move_and_slide(velocity, Vector2.UP)は構文エラーになります。 - velocity に delta を掛けること。
move_and_slide()は物理 delta をすでに考慮しています。velocity = dir * speed * deltaと設定すると、ボディの移動が極端に遅くなります。 _physics_processではなく_processで移動すると、 フレームレートに依存したカクつく動きになります。必ず_physics_processで移動してください。is_on_floor()が常に false になる場合、up_directionが誤っている(デフォルトはVector2.UP)、CollisionShape2Dがない、またはこのフレームでmove_and_slide()を呼び出していない可能性があります。- 床をすり抜ける場合、 通常は衝突形状がない/サイズがゼロ、床のボディがこのボディのマスクに含まれないレイヤーにある、または velocity と
move_and_slide()ではなくposition +=でボディを移動していることが原因です。 - 停止中に坂道を滑る場合:
floor_stop_on_slope = true(デフォルト)を維持し、floor_snap_lengthを設定してボディが下り坂に沿って留まるようにします。
参考資料
- 一方向プラットフォーム、動くプラットフォーム、ジャンプバッファリング、可変ジャンプ高度、
move_and_collide()(手動の衝突応答)については、references/controller-recipes.mdを参照してください。
関連スキル
godot-physics— 衝突レイヤー/マスク、エリア、レイキャスト、剛体。godot-tilemap— キャラクターが歩くレベルの作成。godot-animation— 移動状態に応じたスプライト/スケルタルアニメーションの制御。camera-systems— このキャラクターを追跡する追従カメラ、デッドゾーン、先読み。platformer/input-systems— ジャンル全体のテンプレートと、再割り当て可能な入力。
コメント
Markdown 対応