リアルタイムマルチプレイヤーバーチャルリアリティゲームを構築する方法(パート1)
公開: 2022-03-10このチュートリアルシリーズでは、プレイヤーがパズルを解くために協力する必要があるWebベースのマルチプレイヤー仮想現実ゲームを構築します。 VRモデリングにはA-Frameを使用し、クロスデバイスリアルタイム同期にはMirrorVRを使用し、低ポリの美学にはA-Frame LowPolyを使用します。 このチュートリアルの最後に、誰でもプレイできる完全に機能するデモがオンラインで用意されています。
プレイヤーの各ペアには、オーブのリングが与えられます。 目標は、すべてのオーブを「オン」にすることです。オーブが高くて明るい場合は、オーブが「オン」になります。 オーブが低くて薄暗い場合、オーブは「オフ」になっています。 ただし、特定の「優勢な」オーブは隣接するオーブに影響を与えます。状態を切り替えると、隣接するオーブも状態を切り替えます。 プレーヤー2のみがドミナントオーブを制御でき、プレーヤー1のみが非ドミナントオーブを制御できます。 これにより、両方のプレイヤーが協力してパズルを解く必要があります。 チュートリアルのこの最初の部分では、環境を構築し、VRゲームのデザイン要素を追加します。
このチュートリアルの7つのステップは、次の3つのセクションにグループ化されています。
- シーンの設定(ステップ1〜2)
- オーブの作成(ステップ3〜5)
- オーブをインタラクティブにする(ステップ6〜7)
この最初の部分は、オンとオフを切り替えるクリック可能なオーブで終わります(下の図を参照)。 A-FrameVRといくつかのA-Frame拡張機能を使用します。
シーンの設定
1.基本的なシーンで行こう
はじめに、地面のある単純なシーンを設定する方法を見てみましょう。
以下の最初の3つの手順は、前回の記事から抜粋したものです。 まず、単一の静的HTMLページを使用してWebサイトを設定します。 これにより、デスクトップからコーディングして、Webに自動的にデプロイできます。 展開されたWebサイトは、携帯電話にロードしてVRヘッドセット内に配置できます。 または、デプロイされたWebサイトをスタンドアロンのVRヘッドセットでロードすることもできます。
glitch.comに移動して開始します。 次に、次の手順を実行します。
- 右上の「新規プロジェクト」をクリックし、
- ドロップダウンの「hello-webpage」をクリックし、
- 次に、左側のサイドバーにあるindex.htmlをクリックします。 これをあなたの「編集者」と呼びます。
これで、デフォルトのHTMLファイルを含む次のGlitch画面が表示されます。
上記のリンクされたチュートリアルと同様に、現在のindex.htmlファイル内の既存のコードをすべて削除することから始めます。 次に、A-Frame VRを使用して、基本的なwebVRプロジェクトについて次のように入力します。 これにより、A-Frameのデフォルトの照明とカメラを使用して空のシーンが作成されます。
<!DOCTYPE html> <html> <head> <title>Lightful</title> <script src="https://aframe.io/releases/0.8.0/aframe.min.js"></script> </head> <body> <a-scene> </a-scene> </body> </html>
カメラを立った高さまで上げます。 A-Frame VRの推奨事項(Githubの問題)に従って、カメラを新しいエンティティでラップし、カメラではなく親エンティティを直接移動します。 8行目と9行目a-scene
タグの間に、以下を追加します。
<!-- Camera! --> <a-entity position="0 3 0"> <a-camera wasd-controls look-controls></a-camera> </a-entity>
次に、 a-box
を使用して、地面を示す大きなボックスを追加します。 前の手順のカメラの真下にこれを配置します。
<!-- Action! --> <a-box shadow width="75" height="0.1" depth="75" position="0 -1 0" color="#222"></a-box>
これで、 index.htmlファイルは次のファイルと完全に一致するはずです。 完全なソースコードは、Githubのここにあります。
<html> <head> <title>Lightful</title> <script src="https://aframe.io/releases/0.8.0/aframe.min.js"></script> </head> <body> <a-scene> <!-- Camera! --> <a-entity position="0 3 0"> <a-camera wasd-controls look-controls></a-camera> </a-entity> <!-- Action! --> <a-box shadow width="75" height="0.1" depth="75" position="0 -1 0" color="#222"></a-box> </a-scene> </body> </html>
これでセットアップは完了です。 次に、より神秘的な雰囲気に照明をカスタマイズします。
2.雰囲気を追加します
このステップでは、フォグとカスタム照明を設定します。
霧を追加すると、遠くにあるオブジェクトが見えにくくなります。 8行目のa-scene
タグを変更します。ここでは、地面の端をすばやく覆い隠す暗い霧を追加して、遠くの地平線の効果を与えます。
<a-scene fog="type: linear; color: #111; near:10; far:15"></a-scene>
濃い灰色の#111
は、10の距離から15の距離まで直線的にフェードインします。15単位以上離れたすべてのオブジェクトは完全に隠され、10単位未満の距離のすべてのオブジェクトは完全に表示されます。 間にあるオブジェクトは部分的に隠されています。
ゲーム内のオブジェクトを明るくするために1つのアンビエントライトを追加し、後で追加する反射面を強調するために1方向のライトを追加します。 これは、前の手順で変更したa-scene
タグの直後に配置します。
<!-- Lights! --> <a-light type="directional" castshadow="true" intensity="0.5" color="#FFF" position="2 5 0"></a-light> <a-light intensity="0.1" type="ambient" position="1 1 1" color="#FFF"></a-light>
前の手順のライトの真下に、暗い空を追加します。 濃い灰色の#111
が遠くの霧のそれと一致していることに注意してください。
<a-sky color="#111"></a-sky>
これで、ムードの基本的な変更と、より広義にはシーンのセットアップが完了します。 コードがGithubのステップ2のソースコードと正確に一致していることを確認してください。 次に、低ポリオーブを追加し、オーブの美学のカスタマイズを開始します。
オーブの作成
3.低ポリオーブを作成します
このステップでは、下の図のように、回転する反射オーブを作成します。 オーブは、反射素材を提案するためのいくつかのトリックを備えた2つの定型化された低ポリ球で構成されています。
head
に低ポリゴンライブラリをインポートすることから始めます。 4行目と5行目の間に以下を挿入します。
<script src="https://cdn.jsdelivr.net/gh/alvinwan/[email protected]/dist/aframe-low-poly.min.js"></script>
カルーセル、ラッパー、オーブコンテナを作成します。 carousel
には複数のオーブが含まれ、 wrapper
を使用すると、各オーブを個別に回転させることなく、すべてのオーブを中心軸を中心に回転させることができます。 container
には、名前が示すように、すべてのオーブコンポーネントが含まれます。
<a-entity> <a-entity rotation="0 90 0" class="wrapper" position="0 0 0"> <a-entity class="container" position="8 3 0" scale="1 1 1"> <!-- place orb here --> </a-entity> </a-entity> </a-entity>
オーブコンテナ内に、オーブ自体を追加します。一方の球はわずかに半透明でオフセットされており、もう一方の球は完全に固体です。 2つの組み合わされた模倣反射面。
<a-entity class="orb" data-> <lp-sphere seed="0" shadow max-amplitude="1 1 1" position="-0.5 0 -0.5"></lp-sphere> <lp-sphere seed="0" shadow max-amplitude="1 1 1" rotation="0 45 45" opacity="0.5" position="-0.5 0 -0.5"></lp-sphere> </a-entity>
最後に、最後の命令の.orb
エンティティ内のlp-sphere
の直後に次a-animation
タグを追加して、球を無期限に回転させます。
<a-animation attribute="rotation" repeat="indefinite" from="0 0 0" to="0 360 0" dur="5000"></a-animation>
オーブラッパーとオーブ自体のソースコードは、以下と完全に一致する必要があります。
<a-entity> <a-entity rotation="0 90 0" class="wrapper" position="0 0 0"> <a-entity class="container" position="8 3 0" scale="1 1 1"> <a-entity class="orb" data-> <lp-sphere seed="0" shadow max-amplitude="1 1 1" position="-0.5 0 -0.5"></lp-sphere> <lp-sphere seed="0" shadow max-amplitude="1 1 1" rotation="0 45 45" opacity="0.5" position="-0.5 0 -0.5"></lp-sphere> <a-animation attribute="rotation" repeat="indefinite" from="0 0 0" to="0 360 0" dur="5000"></a-animation> </a-entity> </a-entity> </a-entity> </a-entity>
ソースコードがGithubのステップ3の完全なソースコードと一致することを確認してください。 これで、プレビューは次のように一致するはずです。
次に、黄金色のオーブに照明を追加します。
4.オーブを照らします
このステップでは、2つのライトを追加します。1つはカラー、もう1つはホワイトです。 これにより、以下の効果が得られます。
白色光を追加して、オブジェクトを下から照らします。 ポイントライトを使用します。 #orb0
の直前で、 #container-orb0
内に、次のオフセットポイントライトを追加します。
<a-entity position="-2 -1 0"> <a-light distance="8" type="point" color="#FFF" intensity="0.8"></a-light> </a-entity>
プレビューでは、次のように表示されます。
デフォルトでは、ライトは距離とともに減衰しません。 distance="8"
を追加することにより、ライトが8単位の距離で完全に減衰し、ポイントライトがシーン全体を照らさないようにします。 次に、金色の光を追加します。 最後のライトのすぐ上に以下を追加します。
<a-light class="light-orb" distance="8" type="point" color="#f90" intensity="1"></a-light>
コードがステップ4のソースコードと正確に一致していることを確認してください。 これで、プレビューは次のように一致します。
次に、オーブに最終的な美的修正を加え、回転リングを追加します。
5.リングを追加します
このステップでは、下の図のように、最終的なオーブを作成します。
#orb0
の直前の# #container-orb0
にリングを追加します。
<a-ring color="#fff" material="side:double" position="0 0.5 0" radius-inner="1.9" radius-outer="2" opacity="0.25"></a-ring>
前の手順でポイントライトによって色が染み込んでいるため、リング自体には色が含まれていないことに注意してください。 さらに、 material="side:double"
がないと、リングの裏側がレンダリングされないため、重要です。 これは、リングがその回転の半分の間消えることを意味します。
ただし、上記のコードのみを使用したプレビューは、違いはありません。 これは、リングが現在画面に対して垂直であるためです。 したがって、リングの「側面」(厚さ0)のみが表示されます。 前の手順のa-ring
タグの間に次のアニメーションを配置します。
<a-animation attribute="rotation" easing="linear" repeat="indefinite" from="0 0 0" to="0 360 0" dur="8000"></a-animation>
これで、プレビューは次のように一致するはずです。
回転軸、速度、サイズが異なる可変数のリングを作成します。 次の例のリングを使用できます。 新しいリングは、最後a-ring
下に配置する必要があります。
<a-ring color="#fff" material="side:double" position="0 0.5 0" radius-inner="2.4" radius-outer="2.5" opacity="0.25"> <a-animation attribute="rotation" easing="linear" repeat="indefinite" from="0 45 0" to="360 45 0" dur="8000"></a-animation> </a-ring> <a-ring color="#fff" material="side:double" position="0 0.5 0" radius-inner="1.4" radius-outer="1.5" opacity="0.25"> <a-animation attribute="rotation" easing="linear" repeat="indefinite" from="0 -60 0" to="-360 -60 0" dur="3000"></a-animation> </a-ring>
これで、プレビューは次のように一致します。
コードがGithubのステップ5のソースコードと一致していることを確認してください。 これでオーブの装飾は終わりです。 オーブが完成したら、次にオーブにインタラクティブ機能を追加します。 次のステップでは、クリック可能なオブジェクトをポイントしたときに、クリックアニメーションで表示されるカーソルを具体的に追加します。
オーブをインタラクティブにする
6.カーソルを追加します
このステップでは、クリック可能なオブジェクトをトリガーできる白いカーソルを追加します。 カーソルを下に示します。
a-camera
タグに、次のエンティティを追加します。 fuse
属性により、このエンティティはクリックイベントをトリガーできます。 raycaster
属性は、クリック可能なオブジェクトをチェックする頻度と距離を決定します。 objects
属性は、クリック可能なエンティティを決定するためのセレクターを受け入れます。 この場合、 clickable
可能クラスのすべてのオブジェクトはクリック可能です。
<a-entity cursor="fuse: true; fuseTimeout: 250" position="0 0 -1" geometry="primitive: ring; radiusInner: 0.03; radiusOuter: 0.04" material="color: white; shader: flat; opacity: 0.5" scale="0.5 0.5 0.5" raycaster="far: 20; interval: 1000; objects: .clickable"> <!-- Place cursor animation here --> </a-entity>
次に、美学のためにカーソルアニメーションと追加のリングを追加します。 上記のエンティティカーソルオブジェクト内に以下を配置します。 これにより、カーソルオブジェクトにアニメーションが追加され、クリックが表示されます。
<a-circle radius="0.01" color="#FFF" opacity="0.5" material="shader: flat"></a-circle> <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>
次に、 clickable
クラスを#orb0
に追加して、以下に一致させます。
<a-entity class="orb clickable" data->
コードがGithubのステップ6のソースコードと一致していることを確認してください。 プレビューで、カーソルをそれらからオーブにドラッグして、クリックアニメーションの動作を確認します。 これは下の写真です。
クリック可能な属性は、オーブコンテナではなく、オーブ自体に追加されていることに注意してください。 これは、リングがクリック可能なオブジェクトになるのを防ぐためです。 このように、ユーザーはオーブ自体を構成する球をクリックする必要があります。
このパートの最後のステップでは、オーブのオンとオフの状態を制御するアニメーションを追加します。
7.オーブ状態を追加します
このステップでは、クリックするとオフ状態のオーブをアニメートします。 これは下の写真です。
まず、オーブを縮小して地面に降ろします。 #orb0
orb0の直後の#container-orb0
にa-animation
タグを追加します。 両方のアニメーションはクリックによってトリガーされ、同じイージング機能を共有します-わずかなバウンスのためease-elastic
があります。
<a-animation class="animation-scale" easing="ease-elastic" begin="click" attribute="scale" from="0.5 0.5 0.5" to="1 1 1" direction="alternate" dur="2000"></a-animation> <a-animation class="animation-position" easing="ease-elastic" begin="click" attribute="position" from="8 0.5 0" to="8 3 0" direction="alternate" dur="2000"></a-animation>
オフ状態をさらに強調するために、オーブがオフのときにゴールデンポイントライトを削除します。 ただし、オーブのライトはオーブオブジェクトの外側に配置されます。 したがって、オーブがクリックされたときにクリックイベントがライトに渡されることはありません。 この問題を回避するために、ライトJavascriptを使用してクリックイベントをライトに渡します。 次のアニメーションタグを#light-orb0
します。 ライトは、カスタムswitch
イベントによってトリガーされます。
<a-animation class="animation-intensity" begin="switch" attribute="intensity" from="0" to="1" direction="alternate"></a-animation>
次に、次のクリックイベントリスナーを#container-orb0
に追加します。 これにより、クリックがオーブライトに中継されます。
<a-entity ...>
コードがGithubのステップ7のソースコードと一致していることを確認してください。 最後に、プレビューを引き上げ、カーソルをオーブのオンとオフに移動して、オフとオンの状態を切り替えます。 これは下の写真です。
これで、オーブの双方向性は終了です。 プレイヤーは、自明のオンとオフの状態で、オーブを自由にオンとオフに切り替えることができるようになりました。
結論
このチュートリアルでは、オンとオフの状態を持つ単純なオーブを作成しました。これは、VRヘッドセットに適したカーソルクリックで切り替えることができます。 さまざまな照明技術とアニメーションを使用して、2つの状態を区別することができました。 これで、オーブのバーチャルリアリティデザイン要素は終わりです。 チュートリアルの次のパートでは、オーブに動的にデータを入力し、ゲームメカニズムを追加し、プレーヤーのペア間の通信プロトコルを設定します。