【Godot】CharacterBody2D vs RigidBody2D vs StaticBody2D - Godot Engine 2D物理ボディの使い分け

作成: 2025-12-08

Godot Engineにおける主要な2D物理ボディノード(CharacterBody2D、RigidBody2D、StaticBody2D)の機能、特徴、そしてゲーム開発における適切な使い分けを初心者にも分かりやすく解説

Godot Engineで2Dゲームを開発する際、オブジェクトに「物理的な振る舞い」を持たせるために、どのノードを選択するかは非常に重要です。特に、CharacterBody2DRigidBody2DStaticBody2Dの3つの主要な物理ボディノードは、それぞれ異なる設計思想と用途を持っています。これらを正しく使い分けることは、ゲームのパフォーマンス、制御のしやすさ、そしてバグの少なさに直結します。

本記事では、これら3種類の物理ボディノードの基本的な定義、特徴、そしてどのようなゲームオブジェクトに適用すべきかを、具体的なコード例を交えて徹底的に解説します。

なぜ物理ボディの選択が重要なのか

Godot Engineの物理エンジンは、衝突判定や重力、摩擦といった複雑な計算を自動で行ってくれます。しかし、すべてのオブジェクトを物理エンジン任せにしてしまうと、プレイヤーの意図した動きが実現できなかったり、予期せぬ挙動(バグ)が発生したりする原因となります。

プレイヤーキャラクター のように、開発者が完全に動きを制御したいオブジェクトと、落ちてくる箱 のように物理法則に従って動いてほしいオブジェクトでは、ノードの選択を変える必要があります。この選択こそが、ゲーム開発の効率と品質を左右する最初のステップとなるのです。

3つの主要な物理ボディノードの定義

これら3つのノードは、すべてCollisionObject2Dを継承しており、衝突形状(CollisionShape2D)を持つことができますが、その「動き方」と「制御方法」が根本的に異なります。

1. StaticBody2D(静的なボディ)

StaticBody2Dは、その名の通り「静的(Static)」な物理ボディです。

  • 特徴:
    • 移動しない: 物理エンジンによる影響(重力、力など)を一切受けず、動きません。
    • 衝突の壁: 他の物理ボディとの衝突を検知し、その動きをブロックする「壁」として機能します。
    • 制御: コードでpositionを直接変更することは可能ですが、基本的に移動しないオブジェクトに使用します。
  • 主な用途:
    • 地面、壁、天井、動かないプラットフォーム
    • マップの境界線、障害物

2. RigidBody2D(剛体ボディ)

RigidBody2Dは、物理エンジンによって「剛体(Rigid Body)」として完全にシミュレーションされるボディです。

  • 特徴:
    • 物理エンジン制御: 重力、摩擦、慣性、他のオブジェクトからの力(衝突)など、すべての物理法則に従って動きます。
    • 制御: 開発者は、オブジェクトのpositionを直接操作するのではなく、apply_forceapply_torqueといったメソッドを使って「力」を加えることで動きを制御します。
    • モード: MODE_RIGID(デフォルト)、MODE_STATICMODE_CHARACTERMODE_KINEMATICの4つのモードを持ちますが、通常はデフォルトのMODE_RIGIDで使用します。
  • 主な用途:
    • 落ちてくる箱、ボール、ラグドール(物理演算されたキャラクター)
    • 投擲物、爆発で吹き飛ぶ破片

3. CharacterBody2D(キャラクターボディ)

CharacterBody2Dは、ユーザーがコードで動きを「運動学的(Kinematic)」に制御するために設計されたボディです(Godot 4.0でKinematicBody2Dから名称変更されました)。

  • 特徴:
    • コード制御: 物理エンジンによる力(重力など)の影響は受けますが、他のRigidBody2Dからの衝突によって勝手に動かされることはありません。
    • 移動メソッド: move_and_slide()メソッドを使用して移動します。このメソッドは、移動ベクトルを受け取り、衝突を検知しながら滑らかにオブジェクトを動かす機能を提供します。
    • 柔軟性: プレイヤーの入力に基づいた精密な動き(ジャンプ、ダッシュ、壁登りなど)を実装するのに最適です。
  • 主な用途:
    • プレイヤーキャラクター、敵キャラクター、NPC
    • エレベーターや移動するプラットフォームなど、予測可能な動きをするオブジェクト

物理ボディの比較表

ノード名制御方法物理エンジンの影響他のオブジェクトとの相互作用主な用途
StaticBody2Dなし(固定)受けない衝突をブロックする壁になる地面、壁、動かない障害物
RigidBody2D力(apply_forceなど)受ける(完全にシミュレーション)衝突によって動かされるボール、箱、物理パズル要素
CharacterBody2Dコード(move_and_slide重力などの影響は受ける衝突をブロックするが、動かされないプレイヤー、敵、移動プラットフォーム

実践例:CharacterBody2Dによるプレイヤー制御

ほとんどのゲームで、プレイヤーキャラクターにはCharacterBody2Dを使用します。これは、プレイヤーの入力に対して即座に、かつ予測可能な反応をさせたいからです。RigidBody2Dを使うと、物理演算の遅延や予期せぬ慣性によって、操作感が悪くなることが多いです。

以下は、CharacterBody2Dを使った基本的な移動と重力の実装例です。

extends CharacterBody2D

# 移動速度(ピクセル/秒)
const SPEED = 300.0
# 重力加速度
const JUMP_VELOCITY = -450.0
const GRAVITY = 980.0

# プレイヤーの速度ベクトル
var velocity = Vector2.ZERO

func _physics_process(delta):
    # 1. 重力の適用
    # 地面にいない場合のみ、重力を適用する
    if not is_on_floor():
        velocity.y += GRAVITY * delta

    # 2. 入力の処理
    var direction = Input.get_axis("ui_left", "ui_right")

    # 左右移動
    if direction:
        velocity.x = direction * SPEED
    else:
        # 入力がない場合は滑らかに減速
        velocity.x = move_toward(velocity.x, 0, SPEED)

    # ジャンプ
    if Input.is_action_just_pressed("ui_accept") and is_on_floor():
        velocity.y = JUMP_VELOCITY

    # 3. 移動の実行
    # CharacterBody2Dの核となるメソッド。
    # velocityベクトルに従って移動し、衝突が発生した場合はスライド(滑り)処理を行う。
    move_and_slide()

このコードでは、開発者が直接velocityを操作し、その結果をmove_and_slide()に渡すことで、衝突を考慮した安全かつ精密な移動を実現しています。

適切なノード選択のためのヒント

ノード選択に迷った際は、以下の質問に答えてみてください。

  1. そのオブジェクトは動きますか?
    • No: StaticBody2Dを選択します。(例:壁、地面)
  2. そのオブジェクトの動きを、物理法則(重力、衝突、力)に完全に任せたいですか?
    • Yes: RigidBody2Dを選択します。(例:ボール、箱)
  3. そのオブジェクトの動きを、プレイヤーの入力やAIロジックで精密に制御したいですか?
    • Yes: CharacterBody2Dを選択します。(例:プレイヤー、敵)

特に、プレイヤーキャラクターにはほぼ例外なく CharacterBody2D を使用する と覚えておくと、迷いが少なくなります。RigidBody2Dをプレイヤーに使用すると、物理エンジンの挙動を打ち消すための複雑なコードが必要になり、かえって開発が難しくなることが多いです。

まとめ

Godot Engineの2D物理ボディは、それぞれの役割が明確に分かれています。

  • StaticBody2D: 動かない環境要素。
  • RigidBody2D: 物理法則に完全に委ねるオブジェクト。
  • CharacterBody2D: コードで精密に制御するキャラクター。

これらの違いを理解し、ゲームオブジェクトの性質に合わせて適切なノードを選択することで、よりスムーズで、意図した通りの挙動をするゲーム開発を進めることができるでしょう。