mcpField
G
godot-2d-movement

godot-2d-movement

github.com/gamedev-skills開発5.4k6.8k 回インストール1 日前に更新
リポジトリ

godot-2d-movement について

Godot 4.7でCharacterBody2Dを使った2Dキャラクター移動を実装するためのスキルです。プラットフォーマーや見下ろし型の制御、衝突結果の確認、よくある問題を扱います。

主な機能

  1. 01CharacterBody2Dの移動設定
  2. 02プラットフォーマーの重力とジャンプ
  3. 03見下ろし型の8方向移動
  4. 04スライド衝突と床判定
  5. 05コヨーテタイムの実装例
  6. 06Godot 4.xの移動時の注意点

活用シーン

  1. 01プラットフォーマーの操作キャラクター実装
  2. 02見下ろし型キャラクターの作成
  3. 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。

基本的なワークフロー

  1. CollisionShape2D を子に持つ CharacterBody2D を使用します。 スクリプトで制御するため、単独では落下したり、力に反応したりしません。
  2. velocity プロパティを設定してから、move_and_slide() を呼び出します(4.x では引数を指定しません)。このメソッドは velocity を読み取り、ボディを移動させ、表面に沿って滑らせ、実際の動きを反映するよう velocity を更新します。
  3. _physics_process(delta) 内で実行します。 move_and_slide() は物理ステップの delta を内部で使用するため、自分で velocity に delta を掛けないでください。
  4. プラットフォーマー: 毎ティック velocity.y に重力を加え、is_on_floor() が true のときに velocity.y を負の値に設定してジャンプします。
  5. トップダウン: 入力から方向を作り、速度を掛けます。motion_mode = MOTION_MODE_FLOATING を設定して、「床/壁」の区別がない状態にします。
  6. 呼び出し後に 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 — ジャンル全体のテンプレートと、再割り当て可能な入力。

コメント