入力スムージング
完全に滑らかな動きとカメラを得るためには、入力信号を正しく適用することが必須です。以下のセクションでは、マウスから取得したデータに基づいて、カメラの見た目を回転させることに焦点を当てます。
入力の取得
マウスのデルタは以下を使用して取得します。
UnityEngine.Input.GetAxis("Mouse X")
UnityEngine.Input.GetAxisRaw("Mouse X")
UnityEngine.InputSystem.Mouse.current.delta.ReadValue()
上記のメソッドはすべて、マウスからポーリングされた位置のデルタを後処理なしで返します。マウスのポーリングレート(一般的なのは125Hz、ゲーミングマウスは通常1000Hz)に応じて、マウスで移動したときにMouse X
にこれらの値が返されます。
ご覧のように、それぞれのケースで異なる結果が得られます。ほとんどすべてのケースで、カメラの回転に直接伝播すると、滑らかに見えないという結果になります。サンプルプロジェクトで直接試すことができます。
スムージング
完全に滑らかな見た目を得るためには、2つの解決策が考えられます。
マウスポーリング、エンジン更新レート、モニター更新レートを揃える - 例えば360Hzマウスポーリング、360FPSエンジン更新レート、360Hzモニター更新レート。現実的な解決策ではありません。
入力のスムージング - 数ミリ秒の入力遅延の増加の代償として、ほぼ完全に滑らかな結果が得られます(その違いはハイエンドのゲームセットアップでも顕著です)。
KCCはユーティリティスクリプト SmoothValue
とその亜種である SmoothFloat
, SmoothVector2
, SmoothVector3
を提供しています。
以下のコードでは SmoothVector2
を使って、過去10ミリ秒の値からマウスの位置のデルタを計算しています。
C#
public class PlayerInput : MonoBehaviour
{
// Creates a SmoothVector2 with 128 samples.
private SmoothVector2 _mouseDeltaValues = new SmoothVector2(128);
private void Update()
{
// Read mouse position delta.
Vector2 mouseDelta = Mouse.current.delta.ReadValue();
// Add new value for current frame with delta time since last frame.
_mouseDeltaValues.AddValue(Time.frameCount, Time.unscaledDeltaTime, mouseDelta);
// Calculate smooth mouse delta based on values in last 10 milliseconds.
Vector2 smoothMouseDelta = _mouseDeltaValues.CalculateSmoothValue(0.01, Time.unscaledDeltaTime);
}
}
以下の画像は、さまざまなマウスポーリング速度、エンジン更新速度、およびスムージングウィンドウで、累積されたルック回転(およそ90°)に伝搬されるマウスデルタを示しています。
パープル
- スムージングなし。シアン
- 10msのスムージングウィンドウ。緑色
- 20ms のスムージングウィンドウ。黄色
- 30ms のスムージングウィンドウ。ブルー
- 40ms のスムージングウィンドウ。
一般的に、125Hzのマウスを使用する一般的なユーザーにとって、10~20msのスムージングウィンドウは、滑らかさの向上と応答性の低下の間の良いバランスです。
適切なゲーミングハードウェア(500Hz以上のマウス、120Hz以上のモニター)を使用し、高いエンジン更新レートに達するユーザーには、3~5msのスムージングウィンドウを推奨します。
以下の画像は、90°の累積後のルック回転の詳細を示しています。
スムージングを適用すると、入力ラグに平滑化ウィンドウの長さの30~50%が追加されることがわかります(10msの平滑化ウィンドウを使用した場合、入力ラグは+3.6ms)。
⚠️ グラフはすべて InputSmoothing
シーンを使った Sample Project と Recorders から作成しました。