ノード解説「CharacterBody2D」

はじめに

2DのゲームでプレイヤーキャラクターやNPCを動かしたいとき、衝突判定や物理演算を簡単に扱えるノードが欲しくなります。CharacterBody2Dはまさにそのためのノードで、ゲーム開発で最も使う機会の多いノードの一つです。

この記事では、CharacterBody2Dが何を得意としているのか、どうやって使うのか、そしてより複雑な動きを実装するためのパラメータを解説します。

CharacterBody2Dとは?

CharacterBody2Dは、キャラクターの移動と衝突処理を専門にするノードです。物理エンジンに完全に支配されない(剛体ではない)けれど、壁や床との衝突はきちんと処理する、という微妙なバランスを取ることができます。

CharacterBody2Dは「自分の足で歩く主人公」のようなノード。重力に従うし、壁に激突することもあるけれど、物理の法則に完全には縛られず、プレイヤーの意図通りに動く存在です。

継承ツリーとしては、CharacterBody2D は PhysicsBody2D を継承しており、さらに遡ると Node2D へと続きます。つまり2D空間での位置や回転を持ち、なおかつ物理演算の仕組みに繋がっているとうことです。

このノードを使うべき場面

  • プレイヤーキャラクターの実装: ゲームの主人公を動かす場面。移動入力に応じて歩き、ジャンプし、敵よ障害物に衝突する動作を担当します。
  • 敵キャラクターの移動: AI で制御されるキャラクター。移動経路に沿って歩きながら、地形と衝突判定を自動処理してくれます。
  • グラビティ(重力)が必要な場面: 重力に従って落下するキャラクターは CharacterBody2D があると実装が簡潔です。
  • 滑らかな衝突応答が必要な場面: 移動できないオブジェクト(壁、床)と衝突したときに、キャラクターをスムーズに引っかからせたり、よじ登らせたりする動作。
  • 複数の衝突体とのやり取り: 敵、回復アイテム、ギミックなど、異なる種類のオブジェクトとの相互作用が多い場面。

使わない場面・別のノードが適切な場面

  • RigidBody2D の方が良い場合: 物理エンジンに完全に任せたい場合(例:転がるボール、爆発で吹き飛ぶブロック)。
  • 静的なオブジェクト: 動かない壁や床は CharacterBody2D ではなく StaticBody2D を使います。

主なプロパティと機能

プロパティ・メソッド 説明
velocity キャラクターの速度ベクトル(x, y)。毎フレーム更新して移動させます。
move_and_slide() velocity に従ってキャラクターを動かし、自動的に衝突判定を処理します。
is_on_floor() キャラクターが床の上に立っているかをbool値で返します。
is_on_wall() キャラクターが壁に接触しているかを判定します。
get_last_motion() 最後のmove_and_slide()で実際に移動した距離を取得します。
gravity (プロパティ) キャラクターに加わる重力の大きさ。毎フレーム velocity.y に加算されます。

典型的な使い方を示すコード例です。


extends CharacterBody2D

const SPEED = 200.0
const GRAVITY = 800.0
const JUMP_FORCE = -400.0

func _physics_process(delta: float) -> void:
	# 重力を適用
	if not is_on_floor():
		velocity.y += GRAVITY * delta

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

	# 左右移動入力
	var input_vector = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
	velocity.x = input_vector.x * SPEED

	# 衝突判定を処理しながら移動
	move_and_slide()

もっと使こなす:カスタマイズできるパラメータ

まずは基本を動かしてみてから、余裕が出たら試してみてください。

よく調整するパラメータ

パラメータ 何を変えると何が起きるか
gravity 値を大きくすると落下が速くなります。ゲームの重さ(重力感)を調整するときに変更します。通常800〜1000程度。
max_slides 移動時に壁や床と何回まで衝突判定を繰り返すか。角の引っかかりが激しい場合は増やします(デフォルト4)。
floor_max_angle 床と判定される傾斜の最大角度(ラジアン)〚急な斜面を床と認識させたくない場合は減らします。
wall_min_slide_angle 壁を認識する最小角度。調整することで、キャラクターが壁を「すへる」ではなく「引っかかる」動きになります。
velocity の制限 velocity.y (上晐) に上限を設けることで、落下速度を制限したり、ジャンプの高さを調整したりできます。
衝突層(Collision Layers) キャラクターがどのレイヤーに属し、どのレイヤーと衝突するかを設定。敵とプレイヤーの衝突を別ルイヤーで管理すると整理しやすい。

以下は、より複雑な移動を実装する例です。床の傾きに応じて移動速度を調整するコードです。


extends CharacterBody2D

const MAX_FALL_SPEED = 600.0

func _physics_process(delta: float) -> void:
	# 重力適用
	if not is_on_floor():
		velocity.y += get_gravity() * delta
	else:
		# 床の上にいるときは落下速度をリセット
		velocity.y = 0.0

	# 落下速度の上限を設定
	if velocity.y > MAX_FALL_SPEED:
		velocity.y = MAX_FALL_SPEED

	# 移動実行
	move_and_slide()

まとめ

CharacterBody2D は「キャラクターの移動と衝突を専門にするノード」です。

  • velocity を変更して move_and_slide() を呼ぶだけで、衝突判定が自動的に処理されます。
  • is_on_floor() や is_on_wall() を使えば、キャラクターの状態を細かく制御できます。
  • gravity や max_slides などのパラメータを調整することで、ゲームの操作感を大きく変えられます。

次の記事では、CharacterBody2D を Sprite2D やAnimationPlayer と組み合わせて々実際に歩くキャラクターを作ってみます。

シリーズ:Godot 4 ノード解説

  • 001. ノード解説「Node基底クラス」
  • 002. ノード解説「Node2D」
  • 003. ノード解説「Sprite2D」
  • 004. ノード解説「CollisionShape2D」
  • 005. ノード解説「CharacterBody2D」
  • 006. ノード解説「AnimationPlayer」
  • 007. ノード解説「Timer」
  • 008. ノード解説「Area2D」
  • 009. ノード解説「RigidBody2D」
  • 010. ノード解説「StaticBody2D」
この記事はGodot 4.xをもとに執筆しています

コメント