【Godot4.x】CharacterBody2Dの is_on_floor() と One wayコリジョンの使い方

この記事では、地面への着地判定を行う 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 (トップビュー) のようなゲームと相性が良いです。

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()
📌Godot3.xからの変更点

Godot3.xでは 速度変数を独自に定義する必要がありましたが、Godot4.xからは「velocity」というメンバ変数があらかじめ用意されていて、そこ変数に速度パラメータを加算することで、move_and_velocity() を呼び出したときに自動で移動するように仕様変更されています。

 

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」の項目にチェックを入れるだけです。

 

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

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

完成プロジェクト

今回作成したプロジェクトファイルを添付しておきます。

タイルマップとの衝突

タイルマップとの衝突は以下の記事が参考になると思います。

ジャンプと着地時にスケールする

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