Godotで作るTPS(三人称)カメラ制御
カメラ制御の基本概念
GodotでTPS(三人称視点)のカメラ制御を実装する際に、最も重要なのはプレイヤーキャラクター(以下、プレイヤー)とカメラの関係性です。カメラは常にプレイヤーを追従しつつ、プレイヤーの前後左右、上下といった空間的な位置関係を適切に保つ必要があります。これにより、プレイヤーはゲーム世界を俯瞰し、状況を把握しやすくなります。
カメラの追従性
カメラがプレイヤーを追従する基本的な方法は、カメラノードをプレイヤーノードの子ノードにするか、スクリプトでカメラのトランスフォーム(位置、回転、スケール)をプレイヤーのトランスフォームに同期させることです。
* 子ノード化: 最も簡単な方法です。カメラノードをプレイヤーシーンのルートノードの子として配置します。これにより、プレイヤーが移動するとカメラも自動的に追従します。ただし、この方法だけではカメラの視点がプレイヤーの正面を向いてしまい、見たい方向を自由に操作することができません。
* スクリプトによる同期: プレイヤーノードとは別にカメラノードを配置し、スクリプトでカメラの位置と回転をプレイヤーに追従させる方法です。これはより柔軟な制御を可能にします。例えば、カメラをプレイヤーの背後に一定距離で固定したり、プレイヤーの動きに合わせて滑らかに追従させたりすることができます。
カメラの回転と視点操作
TPSカメラの肝は、プレイヤーが操作する視点移動です。プレイヤーはマウスやゲームパッドのスティックを使ってカメラの向きを変えたいと考えます。これを実現するには、カメラノード自体の回転を直接制御するのではなく、カメラを包含する親ノード(または、カメラとは別の「カメラコントローラー」ノード)の回転を制御するのが一般的です。
* カメラコントローラーノード: プレイヤーノードとは別に、カメラの回転を司るノード(例: Node3D)を作成します。このノードはプレイヤーノードの近くに配置され、プレイヤーの移動に追従しつつ、マウスやスティック入力に応じて自身が回転します。カメラノードはこのカメラコントローラーノードの子ノードとして配置します。こうすることで、カメラコントローラーの回転がカメラの視点となり、プレイヤーはカメラの向きを自在に操作できるようになります。
プレイヤーの向きとカメラの同期
プレイヤーキャラクターの向きとカメラの向きを一致させることも、自然な操作感のために重要です。
* プレイヤーの移動方向とカメラの向き: プレイヤーが移動する際、その移動方向とカメラの向きをある程度同期させることで、プレイヤーは直感的に操作できます。例えば、プレイヤーが前進しているときにカメラがプレイヤーの正面を向いていれば、プレイヤーは進むべき方向を容易に把握できます。
* プレイヤーの回転: プレイヤーキャラクター自体を回転させることで、カメラの向きにプレイヤーの向きを合わせることも可能です。これは、プレイヤーが「カメラの向いている方向に進む」という操作体系の場合に有効です。
具体的な実装テクニック
オフセットと距離
カメラをプレイヤーの背後に配置する際に、カメラとプレイヤーの間に一定のオフセット(距離)を設定します。このオフセットは、プレイヤーの体型やゲームのスタイルに合わせて調整します。
* 固定オフセット: カメラをプレイヤーの背後、特定の座標に配置します。
* 相対オフセット: プレイヤーのトランスフォームからの相対的な位置(例: プレイヤーの後ろ xメートル、上 yメートル)としてカメラの位置を計算します。
スムージング(滑らかな追従)
カメラがプレイヤーに追従する際に、急激な動きではなく、滑らかな動きにすることで、視覚的な快適さを向上させます。
* lerp (Linear Interpolation): Godotのlerp関数やslerp関数(球面線形補間)を使用すると、現在のカメラ位置から目標位置へ、指定した割合で徐々に移動させることができます。これにより、カクカクした動きを防ぎ、滑らかな追従を実現します。
* deltaによる時間経過の考慮: lerp関数の第3引数(補間係数)には、フレームレートに依存しないようにdelta(前フレームからの経過時間)を乗算することが重要です。これにより、フレームレートが変動しても、カメラの移動速度が一定に保たれます。
障害物との干渉回避(カメラコリジョン)
カメラがプレイヤーの視界を遮る壁やオブジェクトにめり込んでしまうと、ゲームプレイが著しく困難になります。これを防ぐために、カメラコリジョンを実装します。
* レイキャスト(Raycast): カメラとプレイヤーの間、またはカメラの目標位置とプレイヤーの間にレイキャスト(光線飛ばし)を行います。レイキャストが何かに衝突した場合、カメラを衝突したオブジェクトの手前まで移動させる、またはプレイヤーに近づけるなどの処理を行います。
* スプリングアーム(SpringArm3D): GodotにはSpringArm3Dノードが用意されており、これはカメラコリジョンを実装するための便利なノードです。SpringArm3Dは、指定した長さだけ伸び、途中に障害物があればそれに当たって縮みます。このノードの先にカメラを配置することで、簡単にカメラコリジョンを実装できます。
カメラのピッチ(上下の視点制限)
カメラの上下の回転(ピッチ)に制限を設けることで、プレイヤーが空を見上げすぎたり、地面を見下ろしすぎたりするのを防ぎ、自然な視野を保ちます。
* 角度制限: カメラコントローラーノードの回転(特にY軸方向の回転)に、最小角度と最大角度を設定します。入力による回転を適用する際に、この制限を超えないようにクランプ(制限値内に丸める)します。
プレイヤーの入力とカメラの連動
プレイヤーの入力(マウス移動、ゲームパッドスティック)をカメラの回転に反映させる処理は、TPSカメラ制御の核心部分です。
* マウス入力:
* マウスのX軸移動は、カメラコントローラーノードのY軸回転(左右への視点移動)に割り当てます。
* マウスのY軸移動は、カメラコントローラーノードのX軸回転(上下の視点移動)に割り当てます。ただし、このX軸回転は、プレイヤーキャラクターの姿勢を崩さないように、カメラコントローラーノードのローカル座標系ではなく、グローバル座標系で適用したり、親ノードの回転と組み合わせて調整したりする必要があります。
* ゲームパッド入力:
* 右スティックのX軸は、カメラコントローラーノードのY軸回転に。
* 右スティックのY軸は、カメラコントローラーノードのX軸回転に。
* マウス入力と同様に、Y軸回転(ピッチ)には角度制限を設けるのが一般的です。
シーン設定とノード構造
GodotでTPSカメラを実装する際の一般的なノード構造は以下のようになります。
“`
– Player (KinematicBody3D or CharacterBody3D)
– MeshInstance3D (Player Model)
– CollisionShape3D
– CameraController (Node3D)
– Camera3D
“`
または、SpringArm3Dを使用する場合:
“`
– Player (KinematicBody3D or CharacterBody3D)
– MeshInstance3D (Player Model)
– CollisionShape3D
– SpringArm3D
– Camera3D
“`
Playerノードはプレイヤーキャラクター本体です。
CameraControllerノード(またはSpringArm3D)は、カメラの回転とプレイヤーからの距離を管理します。
Camera3Dノードは、実際にゲーム画面に表示されるカメラです。
まとめ
GodotでTPSカメラを実装するには、プレイヤーキャラクターの追従、視点操作、そしてそれらを滑らかかつ自然に連携させることが重要です。カメラノードを直接操作するのではなく、カメラを包含する親ノード(カメラコントローラー)の回転を制御し、lerpによるスムージングやSpringArm3Dを用いたカメラコリジョンなどを活用することで、高品質なTPSカメラシステムを構築できます。プレイヤーの入力とカメラの動きを密接に連携させ、必要に応じて視点移動に角度制限を設けることで、操作感の向上と視覚的な快適さを両立させることが可能になります。これらの要素を組み合わせ、ゲームのジャンルやプレイスタイルに合わせて微調整していくことが、魅力的なTPS体験の鍵となります。
