KinematicBody2D(CharacterBody2D)の移動とジャンプ

Gobot

KinematicBody2D(CharacterBody2D)の移動とジャンプ

移動

KinematicBody2D(Godot 4.0以降ではCharacterBody2D)における移動は、その特性上、外部からの直接的な力(重力や慣性など)によってではなく、スクリプトによって意図的に操作されることが前提となっています。

基本的な移動方法

移動の核心は、move_and_slide()メソッド(またはmove_and_collide())にあります。これらのメソッドは、指定された速度ベクトルに基づいてキャラクターを移動させ、壁や地面などのコリジョンオブジェクトとの衝突を処理します。move_and_slide()は、衝突時にオブジェクトを滑らせるため、キャラクターが壁に張り付いて移動するような挙動を自然に実現できます。

速度ベクトルの設定

キャラクターの移動方向と速度は、velocityプロパティにベクトルとして設定されます。例えば、左右への移動はX軸方向の速度、前後(奥行き)への移動はY軸方向の速度(2Dの場合)、あるいはZ軸方向の速度(3Dの場合)を操作することで実現されます。

var velocity = Vector2.ZERO

velocity.x = input_direction.x * SPEED

ここで、input_directionはキーボードやゲームパッドからの入力を受けて生成されるベクトルで、SPEEDはキャラクターの移動速度を定義する定数です。

入力処理と移動方向

キャラクターの移動は、ユーザーからの入力を受け取ることから始まります。Godotでは、InputMapに登録されたアクション(例: “move_left”, “move_right”)を使用して入力を取得するのが一般的です。

キーボード入力の例

“`gdscript
var input_direction = Vector2.ZERO
if Input.is_action_pressed(“move_right”):
input_direction.x += 1
if Input.is_action_pressed(“move_left”):
input_direction.x -= 1
if Input.is_action_pressed(“move_up”):
input_direction.y -= 1 # 2Dの場合、Y軸は上方向がマイナス
if Input.is_action_pressed(“move_down”):
input_direction.y += 1 # 2Dの場合、Y軸は下方向がプラス

velocity.x = input_direction.x * SPEED
velocity.y = input_direction.y * SPEED # 垂直移動も同様に
“`

ただし、2Dプラットフォームゲームなどでは、通常、Y軸方向の入力はジャンプにのみ使用され、水平移動はX軸のみで行われます。

正規化

斜め移動の速度が、水平・垂直移動の速度よりも速くなることを防ぐために、input_directionベクトルを正規化(長さを1にする)することが重要です。これにより、斜め移動時も等速で移動するようになります。

“`gdscript
if input_direction.length() > 0:
velocity.x = input_direction.normalized().x * SPEED
velocity.y = input_direction.normalized().y * SPEED
else:
velocity.x = move_toward(velocity.x, 0, SPEED) # 入力がない場合は減速
velocity.y = move_toward(velocity.y, 0, SPEED)
“`

move_and_slide()の利用

move_and_slide()メソッドは、velocityプロパティに設定された速度でキャラクターを移動させ、衝突を処理します。このメソッドを呼び出すことで、キャラクターは壁にぶつかった際に止まったり、滑ったりします。

“`gdscript
# velocity は既に設定されているものとする
move_and_slide()
“`

Godot 4.0以降のCharacterBody2Dでは、move_and_slide()は自動的にvelocityを更新し、衝突の結果を反映します。以前のKinematicBody2Dでは、get_slide_velocity()などでスライド後の速度を取得する必要がありました。

滑らかな移動と減速

move_toward()関数やlerp()関数を使用することで、移動の開始時や停止時の滑らかなアニメーションを実現できます。これにより、キャラクターの動きがより自然でダイナミックになります。

“`gdscript
# 加速
velocity.x = lerp(velocity.x, input_direction.x * SPEED, ACCELERATION)
# 減速
velocity.x = move_toward(velocity.x, 0, FRICTION)
“`

ジャンプ

ジャンプは、キャラクターの垂直方向の移動を一時的に操作する機能です。重力の影響を受けつつ、上方向への初速度を与えることで実現されます。

重力の実装

キャラクターが地面にいるとき以外は、常に重力の影響を受けて落下するようにする必要があります。これは、velocity.yに重力加速度を加算することで実装されます。

“`gdscript
const GRAVITY = 980 # ゲームのスケールに合わせた重力加速度
if not is_on_floor():
velocity.y += GRAVITY * delta # deltaはフレームごとの時間
“`

is_on_floor()メソッドは、キャラクターが地面に接触しているかどうかを判定します。これは、move_and_slide()が処理した結果に基づいて更新されます。

ジャンプのトリガー

ジャンプは、通常、特定のボタン(例: “jump”アクション)が押されたときに実行されます。しかし、キャラクターが地面にいる場合にのみジャンプできるように制約を設けることが重要です。

“`gdscript
if Input.is_action_just_pressed(“jump”) and is_on_floor():
velocity.y = JUMP_VELOCITY
“`

is_action_just_pressed()は、アクションが押された瞬間のみ true を返します。これにより、ボタンを押しっぱなしにしても複数回ジャンプすることはなくなります。

ジャンプの高さの制御

JUMP_VELOCITYの値を調整することで、ジャンプの高さを制御できます。この値が大きいほど、キャラクターは高くジャンプします。

また、ボタンを離したときにジャンプの勢いを弱めることで、より精密なジャンプ制御(短くボタンを押すと低く、長く押すと高くジャンプするなど)も可能です。

“`gdscript
if Input.is_action_just_pressed(“jump”) and is_on_floor():
velocity.y = JUMP_VELOCITY
elif Input.is_action_just_released(“jump”) and velocity.y < 0:
velocity.y *= 0.5 # ジャンプ中にボタンを離したら、勢いを半分にする
“`

空中での移動

キャラクターが空中にいる場合でも、左右への移動を可能にすることが一般的です。この場合、重力に加えて、水平方向の移動速度を維持または調整します。

“`gdscript
if not is_on_floor():
# 空中での横方向の慣性や減衰などをここで実装
velocity.x = lerp(velocity.x, input_direction.x * AIR_CONTROL_FACTOR, AIR_FRICTION)
“`

AIR_CONTROL_FACTORAIR_FRICTIONといった定数を用いて、空中の操作感を調整します。

まとめ

KinematicBody2D(CharacterBody2D)の移動とジャンプは、velocityプロパティの設定とmove_and_slide()メソッドの活用によって実現されます。基本的な移動は、入力に応じたvelocity.xおよびvelocity.yの設定とmove_and_slide()の呼び出しで完結します。ジャンプは、is_on_floor()で地面判定を行い、上方向への初速度JUMP_VELOCITYを与えることで実装されます。重力は、velocity.yへの継続的な加算によって表現されます。

これらの要素を組み合わせ、lerp()move_toward()のような補間関数や、is_action_just_pressed()のような入力判定を適切に利用することで、プレイヤーが直感的に操作できる、滑らかでレスポンスの良いキャラクターコントローラーを構築することが可能になります。特に、move_and_slide()は衝突処理を自動で行ってくれるため、開発者はキャラクターの移動ロジックに集中できます。Godot 4.0以降では、CharacterBody2Dとしてこれらの機能がより統合され、扱いやすくなっています。