マウス アクセラレーションを無効にして、FPS のゲーム体験を向上させましょう

ウェブアプリで、ポインタ イベントのキャプチャ時にマウスの加速度を無効にできるようになりました。

François Beaufort
François Beaufort

加速移動は、マウスまたはトラックパッドを使用して画面上のポインタを移動する際のエルゴノミクス機能です。ゆっくりと動かすことで正確な移動が可能になり、また、素早く短い動作でポインタを画面全体に移動させることもできます。具体的には、マウスを同じ距離だけ動かした場合、その距離をより速く移動した方が、画面上のポインタの移動距離が長くなります。

オペレーティング システムでは、マウス アクセラレーションがデフォルトで有効になっています。一部のファースト パーソン視点のゲーム(一般的にはファースト パーソン シューティング ゲーム(FPS))では、マウスの未加工の入力データを使用して、加速度調整なしでカメラの回転を制御します。同じ物理的な動き(遅いか速いか)で、同じ回転になります。これにより、プロゲーマーによると、ゲーム エクスペリエンスが向上し、精度が高まります。

Windows 10 の設定にあるポインタの動きのコントロールのスクリーンショット。
Windows 10 の設定でポインタの動きを制御します。

Chrome 88 以降では、更新されたポインタ ロック API により、ウェブアプリで高速化されたマウス移動データと高速化されていないマウス移動データを切り替えることができるようになりました。

Google StadiaNvidia GeForce Now などのウェブベースのゲーム プラットフォームでは、すでにこれらの新機能を使用して FPS ゲーマーを満足させています。

Browser Support

  • Chrome: 37.
  • Edge: 13.
  • Firefox: 50.
  • Safari: 10.1.

Source

API の使用

ポインタ ロックをリクエストする

ポインタ ロックは、デスクトップ アプリケーションがポインタ アイコンを非表示にして、マウスの動きを別のもの(3D 世界の周囲を見回すなど)として解釈する場合の標準的な用語です。

mousemove ドキュメント イベントの movementX 属性と movementY 属性は、最後の移動イベント以降にマウス ポインタが移動した距離を示します。ただし、ポインタがウェブページの外に移動すると、これらの値は更新されません。

document.addEventListener("mousemove", (event) => {
  console.log(`movementX: ${event.movementX} movementY: ${event.movementY}`);
});

マウス ポインタをキャプチャ(またはポインタ ロックをリクエスト)すると、ポインタが外に移動することを心配する必要がなくなります。これは、特に没入型ウェブゲームで役立ちます。ポインタがロックされると、すべてのマウスイベントがポインタ ロックのターゲット要素に送られます。

ターゲット要素で requestPointerLock() を呼び出してポインタ ロックをリクエストし、pointerlockchange イベントと pointerlockerror イベントをリッスンしてポインタ ロックの変更をモニタリングします。

const myTargetElement = document.body;

// Call this function to request a pointer lock.
function requestPointerLock() {
  myTargetElement.requestPointerLock();
}

document.addEventListener("pointerlockchange", () => {
  if (document.pointerLockElement) {
    console.log(`pointer is locked on ${document.pointerLockElement}`);
  } else {
    console.log("pointer is unlocked");
  }
});

document.addEventListener("pointerlockerror", () => {
  console.log("pointer lock error");
});

マウス アクセラレーションを無効にする

{ unadjustedMovement: true } を指定して requestPointerLock() を呼び出し、マウス アクセラレーションの OS レベルの調整を無効にして、マウスの未加工の入力を取得します。これにより、ポインタがロックされている場合、mousemove イベントからのマウス移動データにマウスの加速度が含まれなくなります。

requestPointerLock() から返された新しい Promise を使用して、リクエストが成功したかどうかを確認します。

function requestPointerLockWithUnadjustedMovement() {
  const promise = myTargetElement.requestPointerLock({
    unadjustedMovement: true,
  });

  if (!promise) {
    console.log("disabling mouse acceleration is not supported");
    return;
  }

  return promise
    .then(() => console.log("pointer is locked"))
    .catch((error) => {
      if (error.name === "NotSupportedError") {
        // Some platforms may not support unadjusted movement.
        // You can request again a regular pointer lock.
        return myTargetElement.requestPointerLock();
      }
    });
}

ポインタ ロックを解除せずに、加速されたマウス移動データと加速されていないマウス移動データを切り替えることができます。目的のオプションを指定して、ポインタ ロックを再度リクエストするだけです。そのリクエストが失敗した場合、元のロックはそのまま残り、返された Promise は拒否されます。変更リクエストが失敗した場合、ポインタ ロック イベントは発生しません。

ブラウザ サポート

ポインタ ロック API はブラウザ間で十分にサポートされています。ただし、2020 年 10 月の時点で、マウスの加速度の OS レベルの調整を無効にできるのは Chromium ベースのブラウザ(Chrome、Edge など)のみです。最新情報については、MDN のブラウザの互換性の表をご覧ください。

オペレーティング システムのサポート

マウスの加速度の OS レベルでの調整の無効化は、ChromeOS、macOS Catalina 10.15.1、Windows でサポートされています。Linux は後日対応予定です。

サンプル

サンプルを実行して、Pointer Lock API を試すことができます。

関連情報

謝辞

この記事のレビューをしてくれた James HollyerThomas SteinerJoe MedleyKayce BasquesVincent Scheib に感謝します。