前の記事で、プレイヤーや敵のようにコードで動きを制御したいキャラクターには CharacterBody2D が向いている、と整理しました。
では、CharacterBody2D を選んだあと、インスペクタにある Motion Mode はどう選べばよいのでしょうか。ここを間違えると、横スクロールなのに床判定が不安定になったり、トップダウンなのに床や重力の考え方を持ち込んでコー ドが複雑になったりします。

この記事でわかること
GroundedとFloatingの違い- Motion Modeが「重力のON/OFF」ではない理由
- プラットフォーマーとトップダウンでコードがどう変わるか
is_on_floor()、up_direction、move_and_slide()の関係
Motion Modeは衝突面の解釈を決める
Motion Modeは、ざっくり言うと move_and_slide() が衝突した面をどう扱うかを決める設定です。
Grounded では、衝突した面を 床、壁、天井 として区別します。is_on_floor()、is_on_wall()、is_on_ceiling() のような判定を使いやすくなります。
Floating では、床という考え方を基本的に使いません。トップダウンゲームのように、上下左右どの方向にも同じように移動し、衝突はだいたい「壁」として扱いたい場面に向いています。

重要なのは、Groundedにしただけで重力が自動適用されるわけではない ことです。CharacterBody2DはRigidBody2Dのように物理エンジンへ動きを任せるノードではありません。落下させたいなら、コードで velocity.y に重力を足します。
if not is_on_floor():
# 重力はMotion Modeではなく、コードで加算する
velocity.y += gravity * delta
Motion Modeは「重力をかけるか」ではなく、「衝突した面を床として扱うか、壁として扱うか」に近い設定だと考えると混乱しにくいです。
設定場所
Motion Modeは、CharacterBody2D を選択した状態でインスペクタから変更できます。

スクリプトから設定することもできます。
func _ready() -> void:
# プラットフォーマー向け
motion_mode = CharacterBody2D.MOTION_MODE_GROUNDED
# トップダウン向けにするならこちら
# motion_mode = CharacterBody2D.MOTION_MODE_FLOATING
ただし、通常はインスペクタで設定しておけば十分です。記事内のコードでは分かりやすさのために明示することがありますが、実制作ではキャラクターシーンごとにインスペクタで決める方が見通しが良い場合も多いです。
Grounded: 床とジャンプがあるゲーム
Grounded は、床に立つ、ジャンプする、坂道を歩く、壁にぶつかる、といった横スクロール系のゲームに向いています。
代表例は次の通りです。
- 2Dプラットフォーマー
- メトロイドヴァニア
- 横スクロールアクション
- 重力と床が重要なアクションRPG
基本コードは、重力、ジャンプ、左右移動、move_and_slide() の順に考えます。
extends CharacterBody2D
const SPEED := 260.0
const JUMP_VELOCITY := -420.0
var gravity: float = ProjectSettings.get_setting("physics/2d/default_gravity")
func _physics_process(delta: float) -> void:
if not is_on_floor():
# Groundedでも、重力は自分でvelocityへ足す
velocity.y += gravity * delta
if Input.is_action_just_pressed("jump") and is_on_floor():
# 床にいるときだけジャンプを許可する
velocity.y = JUMP_VELOCITY
var direction := Input.get_axis("move_left", "move_right")
velocity.x = direction * SPEED
# ここで移動し、床/壁/天井の接触状態が更新される
move_and_slide()
is_on_floor() は、直前の move_and_slide() の結果をもとに更新されます。多くのプレイヤー制御では、上のように _physics_process() 内で接地状態を見てジャンプを決め、最後に move_and_slide() を呼びます。
実装レシピ: プラットフォーマーのプレイヤー
プラットフォーマーなら、次の順番で組むと整理しやすいです。
CharacterBody2DのMotion ModeをGroundedにするvelocity.yに重力を加算するis_on_floor()のときだけジャンプを許可する- 左右入力で
velocity.xを決める - 最後に
move_and_slide()を呼ぶ
この形にしておくと、次の段階で可変ジャンプ、コヨーテタイム、ジャンプバッファ、坂道調整を足しやすくなります。床判定が設計の中心になるゲームなら、Groundedから始めるのが自然です。
Floating: 床の概念がいらないゲーム
Floating は、トップダウンゲームのように床や天井を区別しないキャラクターに向いています。
代表例は次の通りです。
- トップダ ウンRPG
- 見下ろし型アクション
- ツインスティックシューター
- 宇宙船の全方向移動
トップダウンでは、重力や is_on_floor() を考えるより、上下左右の入力から移動ベクトルを作る方がシンプルです。
extends CharacterBody2D
const SPEED := 220.0
func _ready() -> void:
motion_mode = CharacterBody2D.MOTION_MODE_FLOATING
func _physics_process(delta: float) -> void:
# 上下左右の入力を1つの方向ベクトルにする
var input_vector := Input.get_vector(
"move_left",
"move_right",
"move_up",
"move_down"
)
velocity = input_vector * SPEED
# Floatingでは床判定より、壁との衝突で止まることが主役
move_and_slide()
このコードには重力もジャンプもありません。プレイヤーは上下左右に動き、壁にぶつかれば止まります。
実装レシピ: トップダウンRPGのプレイヤー
トップダウンRPGなら、次のように考えます。
- Motion Modeを
Floatingにする - InputMapに
move_left/right/up/downを用意する Input.get_vector()で移動方向を作るvelocity = input_vector * speedで速度を決めるmove_and_slide()で壁との衝突を処理する
この形なら、上下左右の移動、斜め移動、ゲームパッド対応をまとめて扱えます。床判定を持ち込まないため、横スクロール用のジャンプコードが混ざらず、読みやすくなります。
ジャンル別の選び方
ゲームジャンルで見ると、Motion Modeの選択はかなり分かりやすくなります。

| ジャンル | 基本の選択 | 理由 |
|---|---|---|
| プラットフォーマー | Grounded | 床、ジャンプ、落下、坂道が重要 |
| メトロイドヴァニア | Grounded | 壁、床、天井、ジャンプ制御を使う |
| トップダウンRPG | Floating | 床判定より上下左右移動が重要 |
| ツインスティックシューター | Floating | 移動方向と照準方向を自由に扱う |
| 宇宙船ゲーム | Floating | 重力に縛られない全方向移動に向く |
迷ったら「ジャンプと床判定がゲームの中心か?」で判断します。中心なら Grounded、中心でないなら Floating を先に試すとよいです。
コード構造の違い
GroundedとFloatingの違いは、コードの流れにも出ます。

Groundedでは、縦方向の状態管理が増えます。
- 重力を足す
- 床にいるか確認する
- ジャンプできるか判断する
- 天井や坂道を考える
Floatingでは、移動方向の計算が中心です。
- 上下左右入力を読む
- 速度ベクトルを作る
- 壁との衝突で止める
- 必要なら照準や向きを別で処理する
この違いを最初に分けておくと、トップダウン用のコードに is_on_floor() が混ざったり、横スクロール用のコードに不要な全方向移動処理が混ざったりしにくくなります。
よくあるつまずき
Groundedにしたのに落下しない
Groundedは「重力を自動でかける設定」ではありません。落下しない場合は、velocity.y += gravity * delta のように重力をコードで足しているか確認してください。
トップダウンなのにis_on_floorを見ている
トップダウンでは、床に立っているかどうかをゲームロジックで使わないことがほとんどです。is_on_floor() に頼る設計になっているなら、横スクロール用の考え方が混ざっている可能性があります。
トップダウンでは、壁にぶつかったか、敵やアイテムに触れたか、攻撃範囲に入ったか、のような判定が中心です。必要なら Area2D やRayCast2Dも組み合わせます。
Floatingなら何でもすり抜けると思っている
Floatingでも、CollisionShape2DやCollision Layer/Maskが正しく設定されていれば、move_and_slide() で壁との衝突を処理できます。
すり抜ける場合は、Motion Modeより先に次を確認します。
CollisionShape2Dがあるか- レイヤーとマスクが合っているか
move_and_slide()を呼んでいるかpositionを直接書き換えていないか
Motion Modeを途中で切り替えすぎる
特殊なゲームでは、通常時はGrounded、水中や宇宙空間ではFloatingのように切り替えることもあります。ただし、初心者のうちは複雑になりやすいです。
モードを切り替えるなら、重力、入力、ジャンプ、摩擦、アニメーションも一緒に切り替える必要があります。単に motion_mode だけ変えても、操作感が自然になるとは限りません。
おまけ: 先に知っておくと良いこと
up_directionは「どちらが上か」を決める
Groundedでは、up_direction が床/壁/天井の判定に関係します。通常の2Dゲームでは Vector2.UP のままで問題ありません。
壁を歩くゲーム、重力方向が変わるゲーム、惑星の表面を歩くゲームでは、この設定が重要になります。ただし通常のプラットフォーマーでは、まずデフォルトで安定した移動を作る方が先です。
floor_snap_lengthは足元の安定に関係する
Groundedでは、坂道や段差で床から一瞬離れたように見えることがあります。floor_snap_length は、床へ吸い付くような挙動に関係します。
この値を調整すると、坂道や下り坂での接地が安定する場合があります。ただし、最初から細かく触るより、基本の重力・ジャンプ・CollisionShape2Dが正しいかを先に確認してください。
Area2Dとの役割は別
トップダウンゲームでは、プレイヤー本体を CharacterBody2D のFloatingにし、攻撃範囲やアイテム取得判定を Area2D にする構成がよくあります。
CharacterBody2D は「移動して壁にぶつかる本体」、Area2D は「触れたことを検出する範囲」と分けると、責務がきれいになります。
まとめ
- Grounded は、床、壁、天井を区別したい横スクロール向け
- Floating は、床の概念がいらないトップダウンや全方向移動向け
- Motion Modeは重力の自動ON/OFFではなく、
move_and_slide()の衝突解釈に関係する - Groundedでも重力はコードで
velocityへ加算する - トップダウンでは
Input.get_vector()とFloatingの組み合わせがシンプル
判断に迷ったら、「このゲームでジャンプと床判定は中心的な仕組みか?」と考えてください。中心ならGrounded、そうでなければFloatingから始めると整理しやすくなります。