リアルタイムのクロスデバイスプレビューでバーチャルリアリティモデルを構築する方法

公開: 2022-03-10
簡単な要約↬このチュートリアルでは、3次元オブジェクトをプログラムし、これらのオブジェクトに簡単な相互作用を追加します。 さらに、クライアントとサーバー間で簡単なメッセージパッシングシステムを構築する方法を学ぶことができます。

バーチャルリアリティ(VR)は、コンピューターで生成された環境に基づくエクスペリエンスです。 さまざまなVR製品が見出しになり、そのアプリケーションは広範囲に及びます。冬季オリンピックでは、米国チームはバーチャルリアリティを運動トレーニングに利用しました。 外科医は医療訓練のためにバーチャルリアリティを実験しています。 そして最も一般的には、仮想現実はゲームに適用されています。

アプリケーションの最後のカテゴリに焦点を当て、特にポイントアンドクリックのアドベンチャーゲームに焦点を当てます。 このようなゲームはカジュアルなクラスのゲームです。 目標は、シーン内のオブジェクトをポイントしてクリックし、パズルを完成させることです。 このチュートリアルでは、そのようなゲームの単純なバージョンを仮想現実で構築します。 これは、3次元でのプログラミングの概要として機能し、仮想現実モデルをWebに展開するための自己完結型の入門ガイドです。 二重の利点を提供するフレームワークであるwebVRを使用して構築します。ユーザーはVRでゲームをプレイでき、VRヘッドセットを持たないユーザーは引き続き電話またはデスクトップでゲームをプレイできます。

バーチャルリアリティのための開発

今日では、どの開発者もVR用のコンテンツを作成できます。 VR開発をよりよく理解するには、デモプロジェクトに取り組むことが役立ちます。 関連記事を読む→

これらのチュートリアルの後半では、デスクトップ用の「ミラー」を作成します。 これは、プレーヤーがモバイルデバイスで行うすべての動きが、デスクトッププレビューにミラーリングされることを意味します。 これにより、プレーヤーが見ているものを確認したり、ガイダンスを提供したり、ゲームを記録したり、単にゲストを楽しませたりすることができます。

前提条件

開始するには、次のものが必要です。 このチュートリアルの後半では、MacOSXが必要になります。 コードはどのプラットフォームにも適用できますが、以下の依存関係のインストール手順はMac用です。

  • 特にglitch.comへのインターネットアクセス。
  • バーチャルリアリティヘッドセット(オプション、推奨)。 私は1枚15ドルで提供されているGoogleCardboardを使用しています。
ジャンプした後もっと! 以下を読み続けてください↓

ステップ1:バーチャルリアリティ(VR)モデルを設定する

このステップでは、単一の静的HTMLページを使用してWebサイトをセットアップします。 これにより、デスクトップからコーディングして、Webに自動的にデプロイできます。 展開されたWebサイトは、携帯電話にロードしてVRヘッドセット内に配置できます。 または、デプロイされたWebサイトをスタンドアロンのVRヘッドセットでロードすることもできます。 glitch.comに移動して開始します。 それで、

  1. 右上の「新規プロジェクト」をクリックします。
  2. ドロップダウンの「hello-express」をクリックします。
glitch.comに移動して開始します
(大プレビュー)

次に、左側のサイドバーにあるviews /index.htmlをクリックします。 これをあなたの「編集者」と呼びます。

次のステップは、左側のサイドバーにあるviews / index.htmlをクリックすることです。これは、これを「エディター」と呼びます。
(大プレビュー)

ウェブページをプレビューするには、左上の「プレビュー」をクリックします。 これをプレビューと呼びます。 エディターでの変更は、バグやサポートされていないブラウザーを除いて、このプレビューに自動的に反映されることに注意してください。

ウェブページをプレビューするには、左上の「プレビュー」をクリックします。これをプレビューと呼びます。エディターでの変更は、バグやサポートされていないブラウザーを除いて、このプレビューに自動的に反映されることに注意してください。
(大プレビュー)

エディターに戻り、現在のHTMLをVRモデルの次の定型文に置き換えます。

 <!DOCTYPE html> <html> <head> <script src="https://aframe.io/releases/0.7.0/aframe.min.js"></script> </head> <body> <a-scene> <!-- blue sky --> <a-sky color="#a3d0ed"></a-sky> <!-- camera with wasd and panning controls --> <a-entity camera look-controls wasd-controls position="0 0.5 2" rotation="0 0 0"></a-entity> <!-- brown ground --> <a-box shadow shadow="receive:true" color="#847452" width="10" height="0.1" depth="10"></a-box> <!-- start code here --> <!-- end code here --> </a-scene> </body> </html>

ナビゲートする以下を参照してください。

プレビューに戻ると、青と茶色の背景色が表示されます。
(大プレビュー)

VRヘッドセットでこれをプレビューするには、オムニバーのURLを使用します。 上の画像では、URLはhttps://point-and-click-vr-game.glitch.me/です。 これで作業環境が設定されました。 このURLを家族や友人と自由に共有してください。 次のステップでは、仮想現実モデルを作成します。

ステップ2:ツリーモデルを構築する

ここで、aframe.ioのプリミティブを使用してツリーを作成します。 これらは、使いやすさのためにAframeが事前にプログラムした標準オブジェクトです。 具体的には、Aframeはオブジェクトをエンティティと呼びます。 ディスカッションを整理するために、すべてのエンティティに関連する3つの概念があります。

  1. 幾何学と材料、
  2. 変換軸、
  3. 相対変換。

まず、ジオメトリマテリアルは、コード内のすべての3次元オブジェクトの2つの構成要素です。 ジオメトリは「形状」を定義します—立方体、球、ピラミッドなど。 マテリアルは、色、反射率、粗さなど、形状の静的プロパティを定義します。

Aframeは、 <a-box><a-sphere><a-cylinder>などのプリミティブを定義して、ジオメトリとそのマテリアルの指定を簡単にすることで、この概念を単純化します。 緑の球を定義することから始めます。 コードの19行目で、 <!-- start code here -->の直後に、次を追加します。

 <!-- start code here --> <a-sphere color="green" radius="0.5"></a-sphere> <!-- new line --> <!-- end code here -->

次に、オブジェクトを変換するための3つの軸があります。 x軸は水平方向に伸びており、右に移動するとx値が増加します。 y軸は垂直方向に伸びており、上に移動するとy値が増加します。 z軸は画面からはみ出し、z値は私たちがあなたに向かって移動するにつれて増加します。 これらの3つの軸に沿って、エンティティを平行移動、回転、またはスケーリングできます。

たとえば、オブジェクトを「正しく」変換するには、そのx値を増やします。 トップのようにオブジェクトを回転させるには、y軸に沿ってオブジェクトを回転させます。 行19を変更して、球を「上」に移動します。これは、球のy値を増やす必要があることを意味します。 すべての変換は<x> <y> <z>として指定されていることに注意してください。つまり、y値を増やすには、2番目の値を増やす必要があります。 デフォルトでは、すべてのオブジェクトは位置0、0、0にあります。以下にposition指定を追加してください。

 <!-- start code here --> <a-sphere color="green" radius="0.5" position="0 1 0"></a-sphere> <!-- edited line --> <!-- end code here -->

第三に、すべての変換はその親に関連しています。 ツリーにトランクを追加するには、上の球の内側に円柱を追加します。 これにより、トランクの位置が球の位置に対して相対的であることが保証されます。 本質的に、これはあなたのツリーを1つのユニットとしてまとめます。 <a-sphere ...> >タグと</a-sphere>タグの間に<a-cylinder>エンティティを追加します。

 <a-sphere color="green" radius="0.5" position="0 1 0"> <a-cylinder color="#84651e" position="0 -0.9 0" radius="0.05"></a-cylinder> <!-- new line --> </a-sphere>

この樹木のない裸の骨を作るには、さらに2つの緑色の球の形で葉を追加します。

 <a-sphere color="green" radius="0.5" position="0 0.75 0"> <a-cylinder color="#84651e" position="0 -0.9 0" radius="0.05"></a-cylinder> <a-sphere color="green" radius="0.35" position="0 0.5 0"></a-sphere> <!-- new line --> <a-sphere color="green" radius="0.2" position="0 0.8 0"></a-sphere> <!-- new line --> </a-sphere>

プレビューに戻ると、次のツリーが表示されます。

プレビューに戻ると、背景に配置された緑の木が表示されます。
(大プレビュー)

VRヘッドセットにウェブサイトのプレビューをリロードし、新しいツリーをチェックしてください。 次のセクションでは、このツリーをインタラクティブにします。

ステップ3:クリックインタラクションをモデルに追加する

エンティティをインタラクティブにするには、次のことを行う必要があります。

  • アニメーションを追加し、
  • クリックするとこのアニメーションがトリガーされます。

エンドユーザーはバーチャルリアリティヘッドセットを使用しているため、クリックすることは凝視することと同じです。つまり、オブジェクトを凝視して「クリック」します。 これらの変更を有効にするには、カーソルから始めます。 13行目を次のように置き換えて、カメラを再定義します。

 <a-entity camera look-controls wasd-controls position="0 0.5 2" rotation="0 0 0"> <a-entity cursor="fuse: true; fuseTimeout: 250" position="0 0 -1" geometry="primitive: ring; radiusInner: 0.02; radiusOuter: 0.03" material="color: black; shader: flat" scale="0.5 0.5 0.5" raycaster="far: 20; interval: 1000; objects: .clickable"> <!-- add animation here --> </a-entity> </a-entity>

上記は、クリックアクションをトリガーできるカーソルを追加します。 objects: .clickableプロパティ。 これは、クラスが「クリック可能」のすべてのオブジェクトがアニメーションをトリガーし、必要に応じて「クリック」コマンドを受け取ることを意味します。 また、クリックカーソルにアニメーションを追加して、カーソルがクリックをトリガーしたことをユーザーが認識できるようにします。 ここでは、クリック可能なオブジェクトをポイントするとカーソルがゆっくりと縮小し、1秒後にスナップして、オブジェクトがクリックされたことを示します。 コメント<!-- add animation here -->を次のコードに置き換えます。

 <a-animation begin="fusing" easing="ease-in" attribute="scale" fill="backwards" from="1 1 1" to="0.2 0.2 0.2" dur="250"></a-animation>

ツリーを2単位右に移動し、29行目を次のように変更して、ツリーに「クリック可能」クラスを追加します。

 <a-sphere color="green" radius="0.5" position="2 0.75 0" class="clickable">

次に、次のことを行います。

  • アニメーションを指定し、
  • クリックでアニメーションをトリガーします。

Aframeの使いやすいアニメーションエンティティにより、両方の手順をすばやく連続して実行できます。

33行目の<a-cylinder>タグの直後で、 </a-sphere>の終わりの前に<a-animation>タグを追加します。

 <a-animation begin="click" attribute="position" from="2 0.75 0" to="2.2 0.75 0" fill="both" direction="alternate" repeat="1"></a-animation>

上記のプロパティは、アニメーションのいくつかの構成を指定します。 アニメーション:

  • clickイベントによってトリガーされます
  • ツリーのposition変更します
  • 元の位置から開始2 0.75 0
  • 2.2 0.75 0で終了0.750(0.2単位右に移動)
  • 目的地への移動および目的地からの移動時にアニメーション化
  • 目的地への移動と目的地からの移動を交互にアニメーション化
  • このアニメーションを1回繰り返します。 これは、オブジェクトが合計2回アニメーション化されることを意味します。1回は宛先に、もう1回は元の位置に戻ります。

最後に、プレビューに移動し、カーソルからツリーにドラッグします。 黒い円が木に載ると、木は右と後ろに移動します。

黒い円が木に載ると、木は右と後ろに移動します。
大きなプレビュー

これで、仮想現実でポイントアンドクリックアドベンチャーゲームを構築するために必要な基本事項は終わりです。 このゲームのより完全なバージョンを表示してプレイするには、次の短いシーンを参照してください。 ミッションは、シーン内のさまざまなオブジェクトをクリックして、ゲートを開き、ゲートの後ろにある木を隠すことです。

ミッションは、シーン内のさまざまなオブジェクトをクリックして、ゲートを開き、ゲートの後ろにある木を隠すことです。
(大プレビュー)

次に、静的デモを提供するための単純なnodeJSサーバーをセットアップします。

ステップ4:NodeJSサーバーをセットアップする

このステップでは、既存のVRモデルを提供する基本的で機能的なnodeJSサーバーをセットアップします。 エディターの左側のサイドバーで、 package.jsonを選択します。

2〜4行目を削除することから始めます。

 "//1": "describes your app and its dependencies", "//2": "https://docs.npmjs.com/files/package.json", "//3": "updating this file will download and update your packages",

名前をmirrorvrに変更します。

 { "name": "mirrorvr", // change me "version": "0.0.1", ...

dependenciesの下に、 socket.ioを追加します。

 "dependencies": { "express": "^4.16.3", "socketio": "^1.0.0", },

現在のグリッチに一致するようにリポジトリのURLを更新します。 グリッチプロジェクトの例は、 point-and-click-vr-gameという名前です。 それをグリッチプロジェクトの名前に置き換えます。

 "repository": { "url": "https://glitch.com/edit/#!/point-and-click-vr-game" },

最後に、 "glitch"タグを"vr"に変更します。

 "keywords": [ "node", "vr", // change me "express" ]

package.jsonが以下と一致することを再確認してください。

 { "name": "mirrorvr", "version": "0.0.1", "description": "Mirror virtual reality models", "main": "server.js", "scripts": { "start": "node server.js" }, "dependencies": { "express": "^4.16.3", "socketio": "^1.0.0" }, "engines": { "node": "8.x" }, "repository": { "url": "https://glitch.com/edit/#!/point-and-click-vr-game" }, "license": "MIT", "keywords": [ "node", "vr", "express" ] }

views/index.htmlで、前の部分のコードが次のコードと一致することを再確認してください。

 <!DOCTYPE html> <html> <head> <script src="https://aframe.io/releases/0.7.0/aframe.min.js"></script> </head> <body> <a-scene> <!-- blue sky --> <a-sky color="#a3d0ed"></a-sky> <!-- camera with wasd and panning controls --> <a-entity camera look-controls wasd-controls position="0 0.5 2" rotation="0 0 0"> <a-entity cursor="fuse: true; fuseTimeout: 250" position="0 0 -1" geometry="primitive: ring; radiusInner: 0.02; radiusOuter: 0.03" material="color: black; shader: flat" scale="0.5 0.5 0.5" raycaster="far: 20; interval: 1000; objects: .clickable"> <a-animation begin="fusing" easing="ease-in" attribute="scale" fill="backwards" from="1 1 1" to="0.2 0.2 0.2" dur="250"></a-animation> </a-entity> </a-entity> <!-- brown ground --> <a-box shadow shadow="receive:true" color="#847452" width="10" height="0.1" depth="10"></a-box> <!-- start code here --> <a-sphere color="green" radius="0.5" position="2 0.75 0" class="clickable"> <a-cylinder color="#84651e" position="0 -0.9 0" radius="0.05"></a-cylinder> <a-sphere color="green" radius="0.35" position="0 0.5 0"></a-sphere> <a-sphere color="green" radius="0.2" position="0 0.8 0"></a-sphere> <a-animation begin="click" attribute="position" from="2 0.75 0" to="2.2 0.75 0" fill="both" direction="alternate" repeat="1"></a-animation> </a-sphere> <!-- end code here --> </a-scene> </body> </html>

既存のserver.jsを変更します。

いくつかのNodeJSユーティリティをインポートすることから始めます。

  • 特急
    これは、サーバーの実行に使用するWebフレームワークです。
  • http
    これにより、デーモンを起動して、さまざまなポートでのアクティビティをリッスンできます。
  • socket.io
    クライアント側とサーバー側の間でほぼリアルタイムで通信できるようにするソケットの実装。

これらのユーティリティをインポートする際に、ExpressJSアプリケーションをさらに初期化します。 最初の2行はすでに書かれていることに注意してください。

 var express = require('express'); var app = express(); /* start new code */ var http = require('http').Server(app); var io = require('socket.io')(http); /* end new code */ // we've started you off with Express,

ユーティリティがロードされると、提供されたサーバーは次に、ホームページとしてindex.htmlを返すようにサーバーに指示します。 以下に記述された新しいコードはないことに注意してください。 これは単に既存のソースコードの説明です。

 // https://expressjs.com/en/starter/basic-routing.html app.get('/', function(request, response) { response.sendFile(__dirname + '/views/index.html'); });

最後に、既存のソースコードは、特に指定がない限り、デフォルトで3000のポートにバインドしてリッスンするようにアプリケーションに指示します。

 // listen for requests :) var listener = app.listen(process.env.PORT, function() { console.log('Your app is listening on port ' + listener.address().port); });

編集が終了すると、Glitchはサーバーを自動的にリロードします。 左上の「表示」をクリックして、アプリケーションをプレビューします。

これで、Webアプリケーションが稼働しています。 次に、クライアントからサーバーにメッセージを送信します。

ステップ5:クライアントからサーバーに情報を送信する

このステップでは、クライアントを使用してサーバーとの接続を初期化します。 クライアントはさらに、サーバーが電話かデスクトップかをサーバーに通知します。 まず、 views/index.html /index.htmlに間もなく存在するJavascriptファイルをインポートします。

4行目以降に、新しいスクリプトを含めます。

 <script src="/client.js" type="text/javascript"></script>

14行目で、カメラエンティティのプロパティのリストにcamera-listenerを追加します。

 <a-entity camera-listener camera look-controls...> ... </a-entity>

次に、左側のサイドバーでpublic/client.jsに移動します。 このファイルのすべてのJavascriptコードを削除します。 次に、クライアントがモバイルデバイスであるかどうかをチェックするユーティリティ関数を定義します。

 /** * Check if client is on mobile */ function mobilecheck() { var check = false; (function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[aw])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))) check = true;})(navigator.userAgent||navigator.vendor||window.opera); return check; };

次に、サーバー側と交換する一連の初期メッセージを定義します。 サーバーへのクライアントの接続を表す新しいsocket.ioオブジェクトを定義します。 ソケットが接続されたら、コンソールにメッセージを記録します。

 var socket = io(); socket.on('connect', function() { console.log(' * Connection established'); });

デバイスがモバイルであるかどうかを確認し、 emit関数を使用して、対応する情報をサーバーに送信します。

 if (mobilecheck()) { socket.emit('newHost'); } else { socket.emit('newMirror'); }

これで、クライアントのメッセージ送信は終了です。 ここで、サーバーコードを修正して、このメッセージを受信し、適切に対応します。 サーバーserver.jsファイルを開きます。

新しい接続を処理し、すぐにクライアントのタイプをリッスンします。 ファイルの最後に、以下を追加します。

 /** * Handle socket interactions */ io.on('connection', function(socket) { socket.on('newMirror', function() { console.log(" * Participant registered as 'mirror'") }); socket.on('newHost', function() { console.log(" * Participant registered as 'host'"); }); });

もう一度、左上の[表示]をクリックしてアプリケーションをプレビューします。 同じURLをモバイルデバイスにロードします。 ターミナルでは、次のように表示されます。

 listening on *: 3000 * Participant registered as 'host' * Participant registered as 'mirror'

これは、クライアントがサーバーに情報を送り返す、最初の単純なメッセージパッシングです。 実行中のNodeJSプロセスを終了します。 このステップの最後の部分では、クライアントにカメラ情報をサーバーに返送させます。 public/client.jsを開きます。

ファイルの最後に、以下を含めます。

 var camera; if (mobilecheck()) { AFRAME.registerComponent('camera-listener', { tick: function () { camera = this.el.sceneEl.camera.el; var position = camera.getAttribute('position'); var rotation = camera.getAttribute('rotation'); socket.emit('onMove', { "position": position, "rotation": rotation }); } }); }

保存して閉じます。 サーバーファイルserver.jsを開いて、このonMoveイベントをリッスンします。

ソケットコードのnewHostブロックに以下を追加します。

 socket.on('newHost', function() { console.log(" * Participant registered as 'host'"); /* start new code */ socket.on('onMove', function(data) { console.log(data); }); /* end new code */ });

もう一度、デスクトップとモバイルデバイスにプレビューをロードします。 モバイルクライアントが接続されると、サーバーはクライアントからサーバーに送信されたカメラの位置と回転の情報の記録をすぐに開始します。 次に、サーバーからクライアントに情報を送り返す逆の方法を実装します。

ステップ6:サーバーからクライアントに情報を送信する

このステップでは、ホストのカメラ情報をすべてのミラーに送信します。 メインサーバーファイルserver.jsを開きます。

onMoveイベントハンドラーを次のように変更します。

 socket.on('onMove', function(data) { console.log(data); // delete me socket.broadcast.emit('move', data) });

broadcast修飾子は、サーバーがこの情報を、元の送信者を除く、ソケットに接続されているすべてのクライアントに送信することを保証します。 この情報がクライアントに送信されたら、それに応じてミラーのカメラを設定する必要があります。 クライアントスクリプトpublic/client.jsを開きます。

ここで、クライアントがデスクトップかどうかを確認します。 その場合は、移動データを受け取り、それに応じてログに記録します。

 if (!mobilecheck()) { socket.on('move', function(data) { console.log(data); }); }

デスクトップとモバイルデバイスにプレビューをロードします。 デスクトップブラウザで、開発者コンソールを開きます。 次に、携帯電話にアプリをロードします。 携帯電話がアプリをロードするとすぐに、デスクトップの開発者コンソールがカメラの位置と回転で点灯するはずです。

public/client.jsで、クライアントスクリプトをもう一度開きます。 最後に、送信された情報に応じてクライアントカメラを調整します。

上記のmoveイベントのイベントハンドラーを修正します。

 socket.on('move', function(data) { /* start new code */ camera.setAttribute('rotation', data["rotation"]); camera.setAttribute('position', data["position"]); /* end new code */ });

デスクトップと携帯電話にアプリをロードします。 お使いの携帯電話のすべての動きは、デスクトップ上の対応するミラーに反映されます! これで、アプリケーションのミラー部分は終わりです。 デスクトップユーザーとして、モバイルユーザーに表示される内容をプレビューできるようになりました。 このセクションで紹介する概念は、シングルプレイヤーをマルチプレイヤーゲームに変換するため、このゲームをさらに発展させるために非常に重要です。

結論

このチュートリアルでは、3次元オブジェクトをプログラムし、これらのオブジェクトに簡単な相互作用を追加しました。 さらに、クライアントとサーバー間で簡単なメッセージパッシングシステムを構築して、モバイルユーザーに表示される内容のデスクトッププレビューを作成しました。

ジオメトリとマテリアルの概念がiOS上のSceneKit(ARKitに関連)、Three.js(Aframeのバックボーン)、およびその他の3次元ライブラリに拡張されるため、これらの概念はwebVRを超えて拡張されます。 これらのシンプルなビルディングブロックを組み合わせることで、本格的なポイントアンドクリックアドベンチャーゲームを柔軟に作成できます。 さらに重要なことに、クリックベースのインターフェイスを使用して任意のゲームを作成できます。

さらに調査するためのいくつかのリソースと例を次に示します。

  • MirrorVR
    上に構築されたライブプレビューの本格的な実装。 たった1つのJavascriptリンクで、モバイル上の仮想現実モデルのライブプレビューをデスクトップに追加します。
  • 少しずつ
    子供の絵のギャラリーと各絵の対応するバーチャルリアリティモデル。
  • フレーム
    例、開発者向けドキュメント、および仮想現実開発のためのその他のリソース。
  • Google Cardboard Experiences
    教育者向けのカスタムツールを使用した教室での体験。

次回は、Webソケットを使用して完全なゲームを構築し、仮想現実ゲームのプレーヤー間のリアルタイム通信を容易にします。 以下のコメントであなた自身のモデルを自由に共有してください。