この記事では、地面への着地判定を行う CharacterBody2Dの is_on_floor() の使い方と、One way 床 (一方通行床) の使い方を解説します。
目次
CharacterBody2D.is_on_floor() の使い方
CharacterBody2Dについて
CharacterBody2Dとは、物理エンジンで動作するノードでありながら、移動パラメータや移動タイミングをスクリプトで指定可能なオブジェクトなります。
物理エンジンで動作する2Dノードとの比較は以下のとおりです。
ノード名 | 物理エンジン での制御 | 用途 |
---|---|---|
RigidBody2D | 自動で動く | 物理制御のみで動く ようなオブジェクト。 粒子やバネ、流体など |
StaticBody2D | 物理制御するが 動かさない オブジェクト | 床や壁など、衝突したときに 動かないが物理制御したいオブジェクト。 スクリプトで動かすことも可能なので、 移動床なども可能 |
CharacterBody2D | スクリプトで 専用の物理関数を 呼び出すことで動く | スクリプトで細かく制御したい 物理オブジェクト。 プレイヤーキャラや敵キャラなど |
RigidBody2D や StaticBody2D は、基本的に物理シミュレーションで動くような Physics puzzle game (物理パズルゲーム) や Sandbox game (サンドボックスゲーム) を作るのに向いています。
RigidBody2D の基本的な使い方は以下の記事に書いていますので、興味があれば参考になるかもしれません。


そしてCharacterBody2D の用途としては、主に 足場をジャンプで飛び移るアクションゲームの 2D Platformer (プラットフォーマー) や Top-down (トップビュー) のようなゲームと相性が良いです。

ラン&ジャンプゲーム

move_and_slide() を使って移動処理を行う
CharacterBody2Dノードには、move_and_slide() というとても便利な関数が用意されています。これを使用した最低限の移動とジャンプを実装したコードは以下のとおりです。
extends CharacterBody2D
const MOVE_SPEED = 50
const DECAY_MOVE_SPEED = 0.9
const GRAVITY = 50
const JUMP_POWER = 1000
func _physics_process(delta: float) -> void:
# 重力を加算
velocity.y += GRAVITY
# 移動量を減衰.
velocity.x *= DECAY_MOVE_SPEED
# 左右移動.
if Input.is_action_pressed("ui_left"):
velocity.x -= MOVE_SPEED # 左方向に移動
elif Input.is_action_pressed("ui_right"):
velocity.x += MOVE_SPEED # 右方向に移動.
# ジャンプ.
if Input.is_action_just_pressed("ui_accept"):
# SPACEキーでジャンプする.
velocity.y = -JUMP_POWER
# 移動処理を行う (velocityの値に delta を掛けた値で移動する)
move_and_slide()

is_on_floor() の使い方
次にジャンプ中かどうかを判定する方法です。CharacterBody2D には is_on_floor() という便利関数が用意されていて、この関数で床の上に乗っているかどうかを簡単に判定できます。
# ジャンプ.
if _is_jumping == false:
# ジャンプ中でなければジャンプできる.
if Input.is_action_just_pressed("ui_accept"):
# SPACEキーでジャンプする.
velocity.y = -JUMP_POWER
# 移動処理.
move_and_slide()
if is_on_floor():
_is_jumping = false # 床に着地している
else:
_is_jumping = true # ジャンプ中.
One way床の使い方
2D Platformer (プラットフォーマー) を作る場合、通り抜けできない床は少し不便です。


もちろんゲームデザイン上、そのような床があっても良いですが、通り抜け可能な床 (一方通行床) があるとステージ設計時に自由度が生まれます。
これを実装するのは簡単で、コリジョンの設定から「One Way Collision」の項目にチェックを入れるだけです。

ちなみにコリジョンを一方通行床にした場合は、エディタ上で矢印が表示されるようになります。

これで上からのみ衝突する床にすることができます。

完成プロジェクト
今回作成したプロジェクトファイルを添付しておきます。
タイルマップとの衝突
タイルマップとの衝突は以下の記事が参考になると思います。


ジャンプと着地時にスケールする
以下はジャンプと着地を気持ちよくするためのスケールを入れたプロジェクトです。
