0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Godot 4】CharacterBody2Dの基本的な移動・衝突処理とGDScript実装まとめ

0
Posted at

Godot Engineで使用するノードに関しての備忘録です。

この記事はGeminiを活用して作成しました。

はじめに

Godot Engine 4で2DのアクションゲームやRPGを作る際、プレイヤーや敵キャラクターの移動・壁との衝突判定にほぼ100%使うのが CharacterBody2D ノードです

この記事では、CharacterBody2D の基本的な仕組みから、Godot 4で推奨される移動テンプレートコードの解説、よくあるトラブルの解決法までをまとめます


1. CharacterBody2Dとは?

Godotの2D物理ボディノードの一つで、「スクリプト(コード)で制御できる物理ボディ」 です

他のノードとの違い(ざっくり比較)

  • StaticBody2D: 壁や床など、動かないオブジェクト用
  • RigidBody2D: 物理エンジン(重力や摩擦など)に挙動を完全に任せるオブジェクト用
  • CharacterBody2D: プレイヤーや敵など、「重力は受けてほしいけれど、ジャンプ力や移動速度はコードで細かく制御したい」 オブジェクト用

2. 基本的なノード構成

CharacterBody2D は単体では動作しません。エディタ上で以下のようにノードを組み合わせるのが基本の形です

  • 📁 CharacterBody2D <--スクリプトをアタッチして移動を制御
    • 📄 Sprite2D または AnimatedSprite2D <--見た目を表示
    • 📄 CollisionShape2D <--当たり判定の形を設定

⚠️ 注意
CollisionShape2D を追加しても「Shape(形状)」を設定しないと、壁や床をすり抜けてしまいます。インスペクターから必ず 新規 RectangleShape2D などを指定してください


3. スクリプト(GDScript)での移動実装

CharacterBody2D ノードにスクリプトを新規作成すると、2D横スクロールアクション用の基本コードが自動生成されます(テンプレートから 「Character Body 2D: Basic Movement」 を選択)

このコードの主要な部分を解剖して解説します

extends CharacterBody2D

# 移動速度とジャンプ力の定義
const SPEED = 300.0
const JUMP_VELOCITY = -400.0

func _physics_process(delta: float) -> void:
    # 1. 重力の適用(床にいない場合のみ)
    if not is_on_floor():
        velocity += get_gravity() * delta

    # 2. ジャンプ入力の処理
    if input.is_action_just_pressed("ui_accept") and is_on_floor():
        velocity.y = JUMP_VELOCITY

    # 3. 左右の入力方向を取得(-1, 0, 1 のいずれかが返る)
    var direction := Input.get_axis("ui_left", "ui_right")
    if direction:
        velocity.x = direction * SPEED
    else:
        # 入力がない場合は減速(摩擦の表現)
        velocity.x = move_toward(velocity.x, 0, SPEED)

    # 4. 超重要:実際に移動させる関数
    move_and_slide()

💡 押さえておきたい Godot 4 のポイント

変数 velocity

Godot 3までは移動関数に速度を渡す必要がありましたが、Godot 4ではノード自体が velocity(Vector2型) という速度プロパティを持っています。この velocity を書き換えてから move_and_slide() を呼ぶだけで移動します

move_and_slide() の仕様変更

引数が不要になりました。この関数を呼ぶと、自動的に velocity を元に移動し、壁や坂道にぶつかると滑らかに滑る(スライドする)移動処理を行ってくれます。さらに、内部で delta(経過時間)を自動計算してくれるため、手動で * delta を掛ける必要はありません(※重力計算など、速度の加算時のみ delta が必要です)

床判定関数

move_and_slide() を実行した直後、以下の便利な判定関数が使えるようになります

  • is_on_floor() : 床に接地しているか(ジャンプの可否判定に便利)
  • is_on_wall() : 壁にぶつかっているか
  • is_on_ceiling() : 天井に頭をぶつけているか

4. トップダウン(全方位)移動にする場合

RPGや全方位シューティングのような「重力がない真上視点」のゲームにする場合は、コードを以下のように書き換えます

extends CharacterBody2D

const SPEED = 300.0

func _physics_process(delta: float) -> void:
    # 上下左右の入力を Vector2 として一括取得
    var direction := Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
    
    if direction:
        velocity = direction * SPEED
    else:
        # 入力がなければスムーズに停止
        velocity = velocity.move_toward(Vector2.ZERO, SPEED)

    move_and_slide()

5. よくあるトラブルと対策

Q. 壁にぶつかったときにガタガタ震える・めり込む

  • 原因: 独自の計算で position(座標)を直接書き換えて移動させていませんか?
  • 対策: position += velocity のような直接書き換えは物理衝突を無視します。必ず velocity を設定して move_and_slide() で移動させるようにしてください

Q. 坂道を上るときに滑り落ちてしまう

  • 対策: CharacterBody2D のインスペクターにある Floor Block On WallFloor Constant Speed をオンにすると、坂道でも滑らずに一定速度で進めるようになります

まとめ

CharacterBody2D は、velocity を書き換えて move_and_slide() を呼ぶ」 という基本さえマスターすれば、あらゆる2Dキャラクターの動きに応用可能です

アニメーションを制御する AnimatedSprite2D と組み合わせることで、一気にゲームらしい挙動が作れるようになるので、ぜひ色々な移動を試してみてください!


参考リンク

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?