メインコンテンツまでスキップ

カメラコントロール

ほとんどのアプリケーションでは、ユーザーがカメラを動かす手段が必要です。これを一から書く代わりに、エンジンに付属する scripts/esm/camera-controls.mjs の CameraControls スクリプトを使用できます。1つのスクリプトで、プロダクション品質のナビゲーションが手に入ります:

  • オービット — マウスの左ドラッグでフォーカスポイントを中心に回転、中ボタンのドラッグでパン、マウスホイールでズームします。
  • フライ — WASDキーでカメラを自由に移動でき、右ボタンのドラッグで視点を動かします。
  • タッチとゲームパッド — マルチタッチジェスチャーとゲームパッド入力を標準でサポートします。

スクリプトをカメラエンティティにアタッチします:

// スクリプトを読み込む(ここではCDNから。アプリにバンドルすることも可能)
const asset = new Asset('camera-controls', 'script', {
url: 'https://cdn.jsdelivr.net/npm/playcanvas/scripts/esm/camera-controls.mjs'
});
app.assets.add(asset);
app.assets.load(asset);

asset.ready(() => {
// カメラエンティティにアタッチする
camera.addComponent('script');
camera.script.create('cameraControls', {
properties: {
focusPoint: new Vec3(0, 1, 0)
}
});
});

バンドラーを使用してアプリをビルドする場合は、代わりにスクリプトクラスを直接インポートできます:

import { CameraControls } from 'playcanvas/scripts/esm/camera-controls.mjs';

camera.addComponent('script');
camera.script.create(CameraControls);

設定​

このスクリプトは豊富な属性を公開しています。よく使われるものは次のとおりです:

属性デフォルト説明
enableOrbittrueオービットコントロールを有効にする
enableFlytrueフライコントロールを有効にする
enablePantrueパンを有効にする
focusPoint[0, 0, 0]カメラが周回する中心点
rotateSpeed0.2回転の感度
moveSpeed10フライの移動速度(moveFastSpeed と moveSlowSpeed のバリエーションあり)
zoomSpeed0.001ズームの感度
pitchRange[-360, 360]カメラのピッチ角の制限(度単位)
zoomRange[0.01, 0]ズーム距離の最小/最大(最大が0の場合は無制限)
leftButtonorbitマウス左ボタンのアクション。マウスボタンを参照
middleButtonpanマウス中ボタンのアクション
rightButtonlookマウス右ボタンのアクション
groundPanfalseビューの平面ではなく地面に沿ってパンする。マップのように地面をドラッグするを参照

ダンピング属性(rotateDamping、moveDamping、zoomDamping、focusDamping、すべてデフォルトは 0.98)は、動きがどれだけ滑らかに減速するかを制御します。0にすると即座に停止します。純粋なオービットカメラを作るにはフライを無効に、純粋なフライカメラを作るにはオービットを無効にしてください。

マウスボタン​

leftButton、middleButton、rightButton 属性で、各マウスボタンの動作を設定します:

アクション説明
orbitフォーカスポイントを中心にビューを回転します。Shiftキーを押している間は、代わりにパンします。
panビューをパンします。
lookキーでフライするときのように、その場でビューを回転します。enableFly がオフの場合は、代わりにオービットします。
noneボタンを無視し、アプリケーションに任せます。

デフォルトでは、左ボタンでオービット、中ボタンでパン、右ボタンでルックします。Editorでは、これらの属性はインスペクターのドロップダウンとして表示されます。たとえば、左ボタンで見回し、右ボタンでオービットするには:

camera.script.create(CameraControls, {
properties: {
leftButton: 'look',
rightButton: 'orbit'
}
});

ドラッグは、それを開始したボタンに従います。ブラウザーは新しい押下として報告しないため、ドラッグ中に2つ目のボタンを押しても何も変わりません。

アプリケーション用にボタンを確保する​

none に設定したボタンは、その押下とそれに続くドラッグの両方が完全に無視されるため、アプリケーションで(たとえばペイントや選択に)使用できます。他のボタンとマウスホイールは引き続きナビゲーションに使えます:

camera.script.create(CameraControls, {
properties: {
rightButton: 'none'
}
});

app.mouse.on(EVENT_MOUSEDOWN, (event) => {
if (event.button === MOUSEBUTTON_RIGHT) {
// ペイントを開始する
}
});

Paintサンプルがこの方法を使っています。

マップのように地面をドラッグする​

デフォルトでは、パンはカメラをビューの平面に沿って移動します。groundPan を有効にすると、ドラッグはマップをドラッグするときのようにカーソルの下の地面の点を保持し、カメラの高さは変わりません。地面は focusPoint の高さにある水平面なので、フォーカスポイントを地面の高さに置いてください。2本指のタッチによるパンも地面に沿って移動します。左ボタンでマップをドラッグし、他のボタンでオービットするには:

camera.script.create(CameraControls, {
properties: {
leftButton: 'pan',
middleButton: 'orbit',
rightButton: 'orbit',
groundPan: true,
focusPoint: new Vec3(0, 0, 0)
}
});

サンプル​

エンジンのサンプルでスクリプトの動作を確認できます:

Orbit Camera
Fly Camera
Multi Camera

独自のカメラロジックを構築したい場合は、Orbit Cameraチュートリアルで完全な実装を解説しています。