入力
非常にスムーズな移動とカメラを実現するには、入力を正しく適用することが必須です。以下のセクションでは、マウスデバイスから受信したデータに基づくカメラ視点回転に焦点を当てます。
入力の取得
マウス移動量は、以下を使用して取得できます。
UnityEngine.Input.GetAxis("Mouse X")UnityEngine.Input.GetAxisRaw("Mouse X")UnityEngine.InputSystem.Mouse.current.delta.ReadValue()
上記メソッドはすべて、マウスから取得した位置差分(ポストプロセスなし)を返します。マウスのポーリングレート(一般的に125Hz、ゲーミングマウスは1000Hz)に応じて、マウスを動かした際のMouse Xは次のような値になります。
ご覧の通り、各ケースで結果が異なります。ほぼすべてのケースにおいて、カメラ回転に直接マウス移動量を適用すれば、視線のムーズさを損なう結果となります。
スムージング
非常にスムーズな結果を得るための解決策は2つあります。
- マウスのポーリングレート・ゲームエンジンのフレームレート・モニターのリフレッシュレートを揃える:例えば、ポーリングレートを360Hz、ゲームエンジンのFPSを360、モニターのリフレッシュレートを360Hzにすることですが、現実的ではありません。
- 入力スムージング:入力遅延が数ミリ秒増加するかわりに、ほぼ完璧にスムーズな結果(ハイエンドゲーミング環境でも差が確認できます)を得られます。
KCCは、便利なスクリプトとしてVector2Accumulatorを提供しています。以下のコードは、過去20ミリ秒の値からスムーズなマウス位置差分を計算する使用例を示しています。
C#
public class PlayerInput : MonoBehaviour
{
// スムージング幅20msのアキュムレーターを作成する
private Vector2Accumulator _lookRotationAccumulator = new Vector2Accumulator(0.02f, true);
private void Update()
{
Vector2 mouseDelta = Mouse.current.delta.ReadValue();
_lookRotationAccumulator.Accumulate(mouseDelta);
}
private void PollInput(CallbackPollInput callback)
{
Quantum.Input input = new Quantum.Input();
// 1. オプション - レンダリング時間に合わせたスムーズなマウス移動量全体を消費する
// input.LookRotationDelta = _lookRotationAccumulator.Consume();
// 2. オプション(推奨) - Quantumフレーム時間に合わせたスムーズなマウス移動量を消費する
// この方法では、視線の回転がtransformに反映される際のスムーズな補間が保証される
input.LookRotationDelta = _lookRotationAccumulator.ConsumeFrameAligned(callback.Game);
callback.SetInput(input, DeterministicInputFlags.Repeatable);
}
}
以下の画像は、様々なマウスのポーリングレート・ゲームエンジンのフレームレート・スムージング幅で、マウス移動量を視線の回転(約90°)に反映した結果を示しています。
Purple- スムージングなしCyan- スムージング幅10msGreen- スムージング幅20msYellow- スムージング幅30msBlue- スムージング幅40ms
一般的に、125Hzのマウスを使用する通常ユーザーにとって、スムージング幅10~20msが滑らかさと応答性のバランスに優れています。
適切なゲーミング環境(500Hz以上のマウスと120Hz以上のモニター)と高いフレームレートを達成しているユーザーにとっては、スムージング幅3~5ms、またはスムージングを完全に無効化するオプションが推奨されます。
以下の画像は、90°蓄積後の視線の回転の詳細を示します。
スムージングを適用すると、スムージング幅の30~50%が入力遅延に追加される(スムージング幅10msを使用する場合、入力遅延が3.6ms増加する)ことがわかります。
Back to top