Godotで作成するFPSの移動とジャンプ
Godot Engineを用いてFPS(ファーストパーソン・シューター)ゲームにおけるキャラクターの移動とジャンプ機能を実装する方法について、技術的な側面から解説します。ここでは、Godotのシーンツリー、ノード、スクリプトの連携を中心に、具体的な実装手順と考慮すべき点について掘り下げていきます。
キャラクターコントローラーの基盤
FPSの移動とジャンプの根幹をなすのは、GodotのCharacterBody3Dノードです。これは、物理演算に基づいたキャラクターの移動を容易にするための専用ノードであり、衝突判定や重力による落下などを自動的に処理してくれます。
CharacterBody3Dノードのセットアップ
まず、新しい3Dシーンを作成し、ルートノードとしてCharacterBody3Dを追加します。このノードに、キャラクターの見た目を表すMeshInstance3Dや、カメラを配置するためのCamera3D、そして当たり判定の形状を定義するCollisionShape3Dを子ノードとして追加します。
CollisionShape3Dには、キャラクターの形状に合ったCapsuleShape3Dなどを設定するのが一般的です。これにより、床や壁との衝突が適切に処理されるようになります。
カメラの親子関係
Camera3Dノードは、CharacterBody3Dノードの子ノードとして配置し、さらにそのCamera3Dノードを、キャラクターの目線となる位置に調整します。これにより、キャラクターの移動に合わせてカメラも追従し、一人称視点でのゲームプレイが可能になります。
移動の実装
キャラクターの移動は、主にキーボード入力に基づいて行われます。Godotでは、InputMapで定義されたアクション(例:「move_forward」「move_backward」など)をスクリプトで検知し、それに応じてCharacterBody3Dノードの速度を変化させることで実装します。
入力処理
`_input(event)`関数や`_process(delta)`関数内で、キーボードイベントを捕捉します。具体的には、`Input.is_action_pressed(“action_name”)`といったメソッドを使用して、指定されたアクションが押されているかどうかを判定します。
速度ベクトル
取得した入力情報から、キャラクターの移動方向を示すベクトルを生成します。例えば、前方移動キーが押されていれば、キャラクターのローカルZ軸方向(通常は前方向)に速度を加算します。左右移動、後方移動も同様に、ローカルX軸方向(通常は右方向)や反対方向のベクトルを考慮して加算します。
transform.basisプロパティを使用することで、キャラクターの現在の向きに基づいた移動ベクトルを簡単に取得できます。例えば、前進は`transform.basis.z`、右移動は`transform.basis.x`となります。
`move_and_slide()`
生成した移動ベクトルをCharacterBody3Dノードのvelocityプロパティに代入し、その後、move_and_slide()`メソッドを呼び出します。このメソッドは、velocityに基づいてキャラクターを移動させ、壁や床との衝突を自動的に処理し、滑るような移動を可能にします。
move_and_slide()`は、与えられた速度ベクトルをそのまま適用するのではなく、物理演算に基づいて衝突を検知し、必要に応じて速度を調整してくれます。これにより、壁にぶつかった際にめり込んだり、床から浮いたりするような不自然な動きを防ぐことができます。
移動速度と加速・減速
移動速度は、グローバル変数やエクスポート変数として定義し、調整可能にします。より滑らかな移動を実現するために、単純な速度の代入だけでなく、徐々に速度を変化させる加速・減速の処理を導入することも考えられます。lerp()`関数などを使用して、現在の速度と目標速度の間で滑らかに補間することで、より洗練された移動感を得ることができます。
ジャンプの実装
ジャンプは、キャラクターが地面にいる場合にのみ実行できるように制御する必要があります。これもCharacterBody3Dノードの機能を利用して実装します。
接地判定
CharacterBody3Dノードには、キャラクターが地面に接触しているかどうかを判定するis_on_floor()`メソッドが用意されています。このメソッドを利用して、ジャンプキーが押された際に、キャラクターが地面にいる場合のみジャンプ処理を実行します。
ジャンプ力
ジャンプの強さは、上方向への速度としてvelocityプロパティに加算します。ジャンプ力は、独立した変数として定義し、調整可能にします。
重力
GodotのCharacterBody3Dノードは、デフォルトで重力の影響を受けるようになっています。ProjectSettings.get_setting(“physics/3d/default_gravity”)から重力加速度を取得し、毎フレームvelocity.yに加算することで、キャラクターが落下するような挙動を再現します。
ジャンプと重力の連動
ジャンプ処理では、上方向への速度を一度だけ与えます。その後は、重力によって自然に落下していくため、ユーザーはジャンプキーを押し続ける必要はありません。この重力による落下と、ジャンプによる上昇が組み合わさることで、自然なジャンプ軌道が描かれます。
カメラの回転(視点操作)
FPSゲームにおいて、プレイヤーがマウス操作で視点を自由に動かせることは非常に重要です。CharacterBody3Dノードの親ノード(通常はゲームシーンのルートノード)を回転させることで、キャラクターの向きを変え、それに応じてカメラの向きも変更します。
マウス入力の取得
マウスの移動量を`_input(event)`関数で取得します。具体的には、`event is InputEventMouseMotion`の条件で、マウスの移動量(`event.relative.x`と`event.relative.y`)を取得します。
水平方向の回転
マウスの水平方向の移動量(`event.relative.x`)は、キャラクター本体の回転に直接影響させます。キャラクターの親ノードの`rotate_y()`メソッドを使用し、マウスの水平移動量に比例した角度で回転させます。これにより、左右への視点移動が実現します。
垂直方向の回転(カメラの上下)
マウスの垂直方向の移動量(`event.relative.y`)は、カメラのみを上下に回転させます。カメラノードの`rotate_x()`メソッドを使用し、マウスの垂直移動量に比例した角度で回転させます。ただし、カメラの上下回転には制限を設けることが重要です。例えば、真上や真下を見すぎないように、一定の範囲内に制限することで、VR酔いのような不快感を軽減できます。
感度調整
マウスの移動量と実際の回転角度の比率を調整する「感度」のパラメータを導入することで、プレイヤーが好みに合わせて視点操作の速さを変更できるようにします。
まとめ
Godot EngineにおけるFPSの移動とジャンプ機能の実装は、CharacterBody3Dノードを中心とした、入力処理、物理演算、そしてカメラ制御の組み合わせによって実現されます。CharacterBody3Dのmove_and_slide()`メソッドやis_on_floor()`メソッドを効果的に活用することで、比較的容易に洗練されたキャラクターコントローラーを構築できます。
移動においては、入力に対する即時的な反応だけでなく、加速・減速処理を導入することで、より自然でプレイヤーが操作していて楽しい感覚を提供できます。ジャンプも、地面判定と重力、そしてジャンプ力の設定を適切に行うことで、リアルな跳躍表現が可能になります。
カメラの回転は、FPSゲームの没入感を大きく左右する要素です。マウス入力とノードの回転を連携させ、さらに回転範囲に制限を設けることで、快適な視点操作を実現できます。これらの要素を組み合わせることで、Godotで本格的なFPSゲームの基礎となるキャラクター操作を実装していくことが可能です。
