🎥

[A-Frame] JavaScriptでカメラの向きを変える方法。気をつけたいこと

2021/07/03に公開


ユーザーが自由に角度を変えられるカメラ。
JavaScriptでも向きを変えることができる。
しかし少し複雑な点があったのでメモを残します。

カメラの用意

よく見かける実装方法を真似て、カメラをentityで囲みます。

<a-entity id="camera-wrapper" rotation="0 0 0" position="0 1.6 0">
  <a-camera
    id="camera"
    position="0 0 0"
    wasd-controls="enabled: false"
  ></a-camera>
</a-entity>

イメージ

赤の四角は、ユーザーが動かすことのできるカメラ(a-camera)。
グレーの四角は、それを囲むwrapper(a-entity)。
黄色の線は、カメラが向いている方向を表しています。

カメラの向きを正面に戻す

ユーザーが、ジャイロやマウスでカメラの向きを変えると、以下のような状態になります。

wrapperはただカメラを囲んでいるだけなので変化はありません。
このような状態からJavaScriptでカメラの向きを正面に直したい場合、
よく見かける方法は、カメラの角度の分だけ、wrapperの角度をマイナスするやり方です。

const cameraRotation = document.getElementById("camera").getAttribute("rotation")
const cameraWrapper = document.getElementById("camera-wrapper")
cameraWrapper.setAttribute("rotation", {
  x: -1 * cameraRotation.x,
  y: -1 * cameraRotation.y,
  z: -1 * cameraRotation.z
})

このように、ユーザーが動かしたカメラの向きをJavaScriptでリセットするだけならこれで問題ありません。
ただし、ここからJavaScriptで特定の方向にカメラを向けたい場合は注意が必要です。

カメラを特定の方向に向ける

ポイントは、カメラはwrapperに対しての相対的な角度であることです。
ここで、真上の天井を見たいとします。
今は正面を見ているからといって、同じようにwrapperのrotationを変更するとこのようになります。(wrapper.rotation.y = 90)

見ている方向を表す黄色い線は、明後日の方向を向いてしまいました。
全然真上を見上げられていない…

このようにユーザーがカメラを一度でも動かすと、カメラとwrapperの角度がバラバラになり、特定の方向に向けるのが難しくなります。
ユーザーはカメラを、JavaScriptはwrapperを動かすから複雑になります。
回避するために、JavaScriptでもカメラのrotationを直接変更します。
以下はカメラを正面に向ける時、wrapperではなくカメラ自体の向きを変更するものです。

const camera = document.getElementById("camera")
camera.components["look-controls"].pitchObject.rotation.x = 0;
camera.components["look-controls"].yawObject.rotation.y = 0;
camera.components["look-controls"].pitchObject.rotation.z = 0;

真上の天井を向く時は

const camera = document.getElementById("camera")
const Y_DEGREE = 90;
const radian = Y_DEGREE * ( Math.PI / 180 )
camera.components["look-controls"].pitchObject.rotation.x = 0;
camera.components["look-controls"].yawObject.rotation.y = radian;
camera.components["look-controls"].pitchObject.rotation.z = 0;

角度はradianにする必要があります。
これでユーザーがカメラの角度を変えた後でも、
JavaScriptで方向を自由に変更できるようになりました!

Discussion