一人称キャラクター
この記事は Godot 3から Godot 4 へ内容の書き換え中です。 Godot4では存在しない変数、関数が含まれている場合があります。もしその場合はリポジトリのIssuesまでご報告ください。
今回の連載では、一人称視点キャラクターの作成方法について解説します。前回作成したCSGベースのレベルを歩行テスト用のステージとして使用し、移動機能を検証していきます。
キャラクターシーン
FPSや類似ゲームにおいて、プレイヤーに「キャラクターの目を通して世界を見ている」という臨場感を与えたいものです。素晴らしい点は、最初はモデル自体が必ずしも必要ではないという点です。
CharacterBody3D オブジェクトを用意します。このオブジェクトに以下の2つの CollisionShape ノードを追加してください。「ボディ用」と「足用」です。また、カメラも必要ですが、回転処理には注意が必要です。キャラクターはY軸に沿ってのみ回転し、一方でカメラのみがX軸方向に回転する必要があります(上下方向の視点移動のため)。これを実現するために、新たに Node3D オブジェクトを作成し、「ピボット」と呼ぶことにします。このピボットノードにCameraを追加してください。
「Body」衝突形状はプレイヤーの身体を表現するものです。ここでは CapsuleShape を使用します(X 軸を中心に90度回転させて設定)。半径を0.5、高さを1に設定してください。
CapsuleShapeを使用する際の問題点は、底面が丸みを帯びている点です。これは小さな障害物を自然に乗り越える際には便利ですが、同時に、プレイヤーが表面の縁に立った場合に「不自然に転がり落ちる」という問題を引き起こします。この問題を解決するには、衝突判定用に「BoxShape」を使用することが有効です。ボックスの範囲は(0.4, 0.1, 0.4)とし、カプセルシェイプの底面より少し上に位置するように配置します。これにより、物体を乗り越えるための丸みを帯びた底面を確保しつつ、箱型形状のおかげで段差から滑り落ちるのを防ぐことができます。
Pivotノードを少し上に移動させ、カメラが身体の中心から外れて向かないようにします。
移動方法
移動関連のコードは、本シリーズで先に紹介した サードパーソン型キャラクターと同様です。まずは変数宣言から始めてください。
extends CharacterBody3D
@onready var camera = $Pivot/Camera
var gravity = -30
var max_speed = 8
var mouse_sensitivity = 0.002 # radians/pixel
var velocity = Vector3()
mouse_sensitivity の値は、マウスの移動距離(ピクセル単位)を角度回転に変換します。つまり、マウスが1ピクセル移動するごとに、0.002ラジアン(約0.1度)だけ回転します。
func get_input():
var input_dir = Vector3()
# desired move in camera direction
if Input.is_action_pressed("move_forward"):
input_dir += -global_transform.basis.z
if Input.is_action_pressed("move_back"):
input_dir += global_transform.basis.z
if Input.is_action_pressed("strafe_left"):
input_dir += -global_transform.basis.x
if Input.is_action_pressed("strafe_right"):
input_dir += global_transform.basis.x
input_dir = input_dir.normalized()
return input_dir
入力を検知した際は、体の向いている方向に移動させたい。
続いて入力値を加算し、最終的な方向ベクトルを返します。
func _unhandled_input(event):
if event is InputEventMouseMotion and Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
rotate_y(-event.relative.x * mouse_sensitivity)
$Pivot.rotate_x(-event.relative.y * mouse_sensitivity)
$Pivot.rotation.x = clamp($Pivot.rotation.x, -1.2, 1.2)
また、カメラ回転用にマウス移動の検出も必要です。前述のとおり、水平方向のマウス移動は身体全体をY軸方向に回転させ、垂直方向の移動では補助ノードをX軸方向に回転させます。
また、カメラが上下逆さまになるのを防ぐため、垂直方向の回転も制限する必要があります。
func _physics_process(delta):
velocity.y += gravity * delta
var desired_velocity = get_input() * max_speed
velocity.x = desired_velocity.x
velocity.z = desired_velocity.z
velocity = move_and_slide(velocity, Vector3.UP, true)
_physics_process()関数内では、desired_velocityを取得します。これはget_input()によって返される方向ベクトルで、これにmax_speedを掛けることで速度ベクトルの長さを調整しています。重力によって設定されているvelocity.yは変更したくないため、入力値に基づいてxとz成分のみを設定しています
move_and_slide()のstop_on_slopeパラメーターにもtrueを設定しています。これにより、スロープに立っても滑り落ちるのを防ぎます。
動作テストを行い、すべてが期待通りに機能していることを確認してください。
武器の追加方法
一人称視点のキャラクターは通常、何らかのアイテムを持っているか、少なくとも手ぶらの場合、その正面に何かが見えているものです。今回は以下のアートパックからショットガンモデルを使用します。
Pivot ノードに MeshInstance を追加し、アートパックに含まれる shotgun.obj モデルを使用してください。このモデルはプレイヤーのスケールに対して小さすぎることが確認できるので、「_Scale」プロパティを (8, 8, 8) に設定してください。
モデルの位置を調整してカメラの「向こう側」に投影されるようが必要です。位置合わせが難しい場合は「ビュー」メニューをクリックし、「2つのビューポート」を選択します。下側のウィンドウで[Camera]を選択し、「プレビュー」をクリックします。上側では、銃が正しく見えるまで移動させることができます。
まとめ
これで基本的な一人称視点キャラクターコントローラーが完成しました。今後のレッスンで学ぶように、機能や動作を追加することで、さまざまなゲームジャンルに対応できる優れた基盤となるはずです。
このレッスンの動画バージョンはこちらでもご覧いただけます。