Loading...

トカチニッチ

北海道十勝の超ローカルウェブメディア「トカチニッチ」ニッチな情報毎日更新中!

Google翻訳

DeviceOrientationControlsを制御してThree.jsスマホVRゲームの基本構造を考える

荒草

荒草

7499 VIEW
投稿記事
注目タグ

※iOS13の判定についてはこちらの記事に書きました↓
 iOS13+でジャイロ許可、やっぱりDeviceOrientationControlsを使いたい
 (2019年10月8日)

過去のThree.js関連記事

Three.jsでスマートフォンなどジャイロセンサー搭載のデバイス向けVR体感型のブラウザゲームを作りたい。そんなとき便利なのがDeviceOrientationControls。スマホの向きに合わせてThree.jsのカメラをぐりぐりと動かしてくれる。

しかしコイツ(DeviceOrientationControls)がかなりの曲者
ジャイロセンサーによる方向の制御が強すぎてカメラを好き勝手にコントロールできないのだ。

最初の記事で挫折したのもそのせい。
半端な理解で、先人のツールに頼ったことの顛末であるが、今回の記事でリベンジできた。

最近VRばんえい競馬ゲームを作成したことで、どうしてもDeviceOrientationControlsの向きを制御する必要があった。正規の方法もあるのだろうが、深く調べる前に“ウマイ”解決策を思いついたので記録に残す。

本当に解決策を探してる人のために先に答え
DeviceOrientationControlsで方向を取得するだけのカメラとキャンパスに描画するカメラを分けたらOKでした。

今回作ったもの

開始したときと左上にある「リセット」ボタンを押したとき必ず馬のいる方向にカメラを向けるという単純に見えて、なかなか(DeviceOrientationControlsのときに限り)難しかったプログラム。

例によって、ジャイロセンサー搭載のデバイスには「DeviceOrientationControls」。PCなどそうでない端末には「OrbitControls」という変わり映えしない構成。

今回のテーマは前者。
ジャイロセンサー搭載のデバイスには「DeviceOrientationControls」の部分。スマホの向きによって動かせるカメラになるが、ゲームである以上“ゲームの開始時”、または“ゲームのリセット時”に必ず一定の方向を向かせる必要があった。

前回の記事「使えるパノラマビューア」では一定の方向を向かせるため、カメラでなく映す対象の方を動かした。しかしパノラマビューアのような単純なものならともかく、ぐりぐりと移動が必要なゲームの場合、対象の向きを動かすのは無理がある。

やはりカメラの向き、アングルを動かす方がシンプルで楽なのだ。

工夫したのはこの部分

//スマホなどジャイロセンサーが有効なときはカメラを2台使う
if(isGyro){
	//通常カメラ
	camera=new THREE.PerspectiveCamera(opt.camera.fov,cv._w/cv._h,opt.camera.near,opt.camera.far);
	camera.position.set(0,0,0.01);
	camera.lookAt(new THREE.Vector3(0,0,0));

	//ジャイロセンサーによる角度を取得する目的だけのカメラ
	camera_doc=new THREE.PerspectiveCamera(opt.camera.fov,cv._w/cv._h,opt.camera.near,opt.camera.far);
	camera_doc.position.set(0,0,0.01);
	camera_doc.lookAt(new THREE.Vector3(0,0,0));

	controls=new THREE.DeviceOrientationControls(camera_doc);
	controls.connect();

実際に描画するカメラ「camera」とDeviceOrientationControlsの方向を取得するためだけのカメラ「camera_doc」を用意。

そして開始時やリセット時にDeviceOrientationControlsが当てられた「camera_doc」の方向(※ジャイロセンサーによるアングル)を保存しておく↓

controls.update();
camera_defx=camera_doc.rotation.x;
camera_defy=camera_doc.rotation.y;
camera_defz=camera_doc.rotation.z;

runAnimateの中で先ほど保存しておいた方向と現在の「camera_doc」の方向の差分を計算し描画用カメラである「camera」に反映する↓

if(isGyro){
	var camera_nowx=camera_doc.rotation.x;
	var camera_nowy=camera_doc.rotation.y;
	var camera_nowz=camera_doc.rotation.z;

	//Y方向のみ制御する場合
	camera.rotation.x=camera_nowx;
	camera.rotation.y=(camera_defy-camera_nowy)*-1;
	camera.rotation.z=camera_nowz;

	//全方向参照する場合
	//camera.rotation.x=(camera_defx-camera_nowx)*-1;
	//camera.rotation.y=(camera_defy-camera_nowy)*-1;
	//camera.rotation.z=(camera_defz-camera_nowz)*-1;
}

ただカメラのX方向、Z方向まで制御しようとするとDeviceOrientationControlsのせいでやはり真上/真下を向いた際に挙動がおかしくなる。
Y方向だけ制御できれば十分だと思うのだがいかがだろうか。
※寝ながらVRゲームをするのはやめましょう。

まとめ

繰り返しになってしまうが、スマホVRゲームの基本構造としてジャイロセンサー搭載のデバイスには「DeviceOrientationControls」で、PCなどそうでない端末には「OrbitControls」を使用する。
そして「DeviceOrientationControls」の場合はさらにカメラを2台構成にしてカメラのアングルを制御してみてはいかがか、という提案である。


使用したパノラマ画像は十勝川、十勝大橋付近。
先の台風災害前に撮影した、哀しくも懐かしい自然あふれる河川風景。

PRAmazonで「Three.js」を探す!


この記事が気に入ったら

※現在、こちらのコメント欄でのご質問・お問い合わせは受付けておりません。 恐れ入りますが、ご利用に関する不明点などは「お問い合わせフォーム」よりご連絡ください。

※投稿内容に関係のないコメントや、不適切な表現に該当すると判断したコメントは、投稿者に断りなく削除する場合があります。

荒草て未来から来たの?ターミネーターなの?

ヤバい最初の5行で挫折した\(^o^)/
とにかくテクノロジー!!

や、やっぱりかわいい❗馬❗

ミスターニッチ!

  • コメント
  • ランキング
  • オススメ
コメント一覧
ランキング一覧
オススメ一覧