Cum să construiți un model de realitate virtuală cu o previzualizare în timp real pe mai multe dispozitive

Publicat: 2022-03-10
Rezumat rapid ↬ În acest tutorial, vom programa obiecte tridimensionale și vom adăuga interacțiuni simple la aceste obiecte. În plus, puteți învăța cum să construiți un sistem simplu de transmitere a mesajelor între clienți și servere.

Realitatea virtuală (VR) este o experiență bazată într-un mediu generat de computer; o serie de produse VR diferite fac titluri, iar aplicațiile sale variază în mare măsură: pentru Jocurile Olimpice de iarnă, echipa SUA a folosit realitatea virtuală pentru antrenamentul atletic; chirurgii experimentează realitatea virtuală pentru pregătirea medicală; și cel mai frecvent, realitatea virtuală este aplicată la jocuri.

Ne vom concentra pe ultima categorie de aplicații și ne vom concentra în mod special pe jocurile de aventură point-and-click . Astfel de jocuri sunt o clasă casual de jocuri; scopul este să îndreptați și să faceți clic pe obiecte din scenă, pentru a termina un puzzle. În acest tutorial, vom construi o versiune simplă a unui astfel de joc, dar în realitate virtuală. Acesta servește ca o introducere în programarea în trei dimensiuni și este un ghid de început autonom pentru implementarea unui model de realitate virtuală pe web. Veți construi cu webVR, un cadru care oferă un dublu avantaj - utilizatorii vă pot juca jocul în VR, iar utilizatorii fără căști VR vă pot juca jocul pe un telefon sau desktop.

Dezvoltare pentru realitate virtuală

Orice dezvoltator poate crea conținut pentru VR în zilele noastre. Pentru a înțelege mai bine dezvoltarea VR, lucrul cu un proiect demonstrativ poate ajuta. Citiți un articol înrudit →

În a doua jumătate a acestui tutorial, veți construi apoi o „oglindă” pentru desktop. Aceasta înseamnă că toate mișcările pe care jucătorul le face pe un dispozitiv mobil vor fi reflectate într-o previzualizare desktop. Acest lucru vă permite să vedeți ceea ce vede jucătorul, permițându-vă să oferiți îndrumări, să înregistrați jocul sau pur și simplu să distrați oaspeții.

Cerințe preliminare

Pentru a începe, veți avea nevoie de următoarele. Pentru a doua jumătate a acestui tutorial, veți avea nevoie de un Mac OSX. În timp ce codul se poate aplica oricărei platforme, instrucțiunile de instalare a dependenței de mai jos sunt pentru Mac.

  • acces la internet, în special la glitch.com;
  • Un set cu cască de realitate virtuală (opțional, recomandat). Folosesc Google Cardboard, care este oferit la 15 USD bucata.
Mai multe după săritură! Continuați să citiți mai jos ↓

Pasul 1: Configurarea unui model de realitate virtuală (VR).

În acest pas, vom configura un site web cu o singură pagină HTML statică. Acest lucru ne permite să codificăm de pe desktop și să îl implementăm automat pe web. Site-ul web implementat poate fi apoi încărcat pe telefonul mobil și plasat într-o cască VR. În mod alternativ, site-ul web implementat poate fi încărcat de o cască VR autonomă. Începeți prin a naviga la glitch.com. Apoi,

  1. Faceți clic pe „Proiect nou” în dreapta sus.
  2. Faceți clic pe „hello-express” în meniul drop-down.
Începeți prin a naviga la glitch.com
(Previzualizare mare)

Apoi, faceți clic pe views/index.html în bara laterală din stânga. Ne vom referi la asta drept „editorul tău”.

Următorul pas ar fi să faceți clic pe views/index.html din bara laterală din stânga, care va fi numită „editorul dumneavoastră”.
(Previzualizare mare)

Pentru a previzualiza pagina web, faceți clic pe „Previzualizare” în stânga sus. Ne vom referi la aceasta ca previzualizare . Rețineți că orice modificare în editorul dvs. se va reflecta automat în această previzualizare, cu excepția erorilor sau a browserelor neacceptate.

Pentru a previzualiza pagina web, faceți clic pe „Previzualizare” în stânga sus. Ne vom referi la aceasta ca previzualizare. Rețineți că orice modificare în editorul dvs. se va reflecta automat în această previzualizare, cu excepția erorilor sau a browserelor neacceptate.
(Previzualizare mare)

Înapoi în editorul dvs., înlocuiți codul HTML actual cu următorul boilerplate pentru un model 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>

Navigați, vedeți următoarele.

Când navigați înapoi la previzualizare, veți vedea culorile de fundal albastru și maro.
(Previzualizare mare)

Pentru a previzualiza acest lucru pe căștile dvs. VR, utilizați adresa URL din bara omnibară. În imaginea de mai sus, adresa URL este https://point-and-click-vr-game.glitch.me/ . Mediul dumneavoastră de lucru este acum configurat; nu ezitați să distribuiți această adresă URL cu familia și prietenii. În pasul următor, veți crea un model de realitate virtuală.

Pasul 2: Construiește un model de arbore

Acum veți crea un arbore, folosind primitive din aframe.io. Acestea sunt obiecte standard pe care Aframe le-a preprogramat pentru ușurință în utilizare. Mai exact, Aframe se referă la obiecte ca entități . Există trei concepte, legate de toate entitățile, pentru a ne organiza discuția în jurul:

  1. Geometrie și material,
  2. Axe de transformare,
  3. Transformări relative.

În primul rând, geometria și materialul sunt două blocuri de construcție ale tuturor obiectelor tridimensionale din cod. Geometria definește „forma” - un cub, o sferă, o piramidă și așa mai departe. Materialul definește proprietățile statice ale formei, cum ar fi culoarea, reflectivitatea, rugozitatea.

Aframe simplifică acest concept pentru noi prin definirea unor primitive, cum ar fi <a-box> , <a-sphere> , <a-cylinder> și multe altele pentru a simplifica specificarea unei geometrii și a materialului acesteia. Începeți prin a defini o sferă verde. Pe linia 19 din codul dvs., imediat după <!-- start code here --> , adăugați următoarele.

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

În al doilea rând, există trei axe pentru a ne transforma obiectul. Axa x rulează orizontal, unde valorile x cresc pe măsură ce ne deplasăm la dreapta. Axa y rulează vertical, unde valorile y cresc pe măsură ce ne deplasăm în sus. Axa z iese din ecran, unde valorile z cresc pe măsură ce ne îndreptăm spre tine. Putem traduce, roti sau scala entități de-a lungul acestor trei axe.

De exemplu, pentru a traduce un obiect „drept”, îi creștem valoarea x. Pentru a roti un obiect ca un vârf, îl rotim de-a lungul axei y. Modificați linia 19 pentru a muta sfera „în sus” - aceasta înseamnă că trebuie să creșteți valoarea y a sferei. Rețineți că toate transformările sunt specificate ca <x> <y> <z> , adică pentru a crește valoarea y, trebuie să creșteți a doua valoare. În mod implicit, toate obiectele sunt situate la poziția 0, 0, 0. Adăugați mai jos specificația position .

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

În al treilea rând, toate transformările sunt relative la părintele său. Pentru a adăuga un trunchi la copac, adăugați un cilindru în interiorul sferei de deasupra. Acest lucru asigură că poziția trunchiului este relativă la poziția sferei. În esență, acest lucru vă menține copacul împreună ca o singură unitate. Adăugați entitatea <a-cylinder> între etichetele <a-sphere ...> și </a-sphere> .

 <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>

Pentru a face acest barebones fără copaci, adăugați mai mult frunziș, sub forma a încă două sfere verzi.

 <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>

Navigați înapoi la previzualizare și veți vedea următorul arbore:

Când navigați înapoi la previzualizare, acum veți putea vedea un copac verde plasat în fundal.
(Previzualizare mare)

Reîncărcați previzualizarea site-ului pe căștile dvs. VR și verificați noul arbore. În secțiunea următoare, vom face acest arbore interactiv.

Pasul 3: Adăugați interacțiunea clic la model

Pentru a face o entitate interactivă, va trebui să:

  • Adăugați o animație,
  • Declanșează această animație la clic.

Deoarece utilizatorul final folosește un set cu cască de realitate virtuală, clicul este echivalent cu privirea: cu alte cuvinte, priviți un obiect pentru a „face clic” pe el. Pentru a efectua aceste modificări, veți începe cu cursorul. Redefiniți camera, înlocuind linia 13 cu următoarele.

 <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>

Cele de mai sus adaugă un cursor care poate declanșa acțiunea de clic. Observați objects: .clickable . Aceasta înseamnă că toate obiectele cu clasa „clickable” vor declanșa animația și vor primi o comandă „click” acolo unde este cazul. Veți adăuga, de asemenea, o animație la cursorul de clic, astfel încât utilizatorii să știe când cursorul declanșează un clic. Aici, cursorul se va micșora lent când indică un obiect pe care se poate face clic, fixându-se după o secundă pentru a indica că un obiect a fost făcut clic. Înlocuiește comentariul <!-- add animation here --> cu următorul cod:

 <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>

Mutați arborele la dreapta cu 2 unități și adăugați clasa „clickable” la arbore, modificând linia 29 pentru a se potrivi cu următoarele.

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

În continuare, vei:

  • Specificați o animație,
  • Declanșați animația cu un clic.

Datorită entității de animație Aframe ușor de utilizat, ambii pași se pot face în succesiune rapidă.

Adăugați o etichetă <a-animation> pe linia 33, imediat după eticheta <a-cylinder> , dar înainte de sfârșitul </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>

Proprietățile de mai sus specifică un număr de configurații pentru animație. Animația:

  • Este declanșat de evenimentul click
  • Modifică position arborelui
  • Pornește de la poziția inițială 2 0.75 0
  • Se termină în 2.2 0.75 0 (se deplasează cu 0,2 unități la dreapta)
  • Se afișează atunci când călătoriți către și de la destinație
  • Alternează animația între călătoriile către și de la destinație
  • Repetă această animație o dată. Aceasta înseamnă că obiectul se anime de două ori în total - o dată la destinație și o dată înapoi la poziția inițială.

În cele din urmă, navigați la previzualizare și trageți de la cursor în arbore. Odată ce cercul negru se sprijină pe copac, copacul se va deplasa la dreapta și înapoi.

Odată ce cercul negru se sprijină pe copac, copacul se va deplasa la dreapta și înapoi.
Previzualizare mare

Aceasta încheie elementele de bază necesare pentru a construi un joc de aventură point-and-click, în realitate virtuală. Pentru a vizualiza și a juca o versiune mai completă a acestui joc, vedeți următoarea scenă scurtă. Misiunea este de a deschide poarta și a ascunde copacul în spatele porții, făcând clic pe diverse obiecte din scenă.

Misiunea este de a deschide poarta și a ascunde copacul în spatele porții, făcând clic pe diverse obiecte din scenă.
(Previzualizare mare)

Apoi, am configurat un server simplu nodeJS pentru a servi demonstrația noastră statică.

Pasul 4: Configurați serverul NodeJS

În acest pas, vom configura un server nodeJS de bază, funcțional, care deservește modelul dvs. VR existent. În bara laterală din stânga a editorului, selectați package.json .

Începeți prin a șterge rândurile 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",

Schimbați numele în mirrorvr .

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

Sub dependencies , adăugați socket.io .

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

Actualizați adresa URL a depozitului pentru a se potrivi cu erorile actuale. Exemplul de proiect glitch se numește point-and-click-vr-game . Înlocuiește-l cu numele proiectului tău glitch.

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

În cele din urmă, schimbați eticheta "glitch" în "vr" .

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

Verificați de două ori dacă package.json dvs. se potrivește acum cu următoarele.

 { "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" ] }

Verificați de două ori dacă codul dvs. din părțile anterioare se potrivește cu următoarele, în 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>

Modificați server.js existent.

Începeți prin a importa mai multe utilitare NodeJS.

  • Expres
    Acesta este cadrul web pe care îl vom folosi pentru a rula serverul.
  • http
    Acest lucru ne permite să lansăm un daemon, ascultând activitatea pe diferite porturi.
  • socket.io
    Implementarea socket-urilor care ne permite să comunicăm între partea client și partea serverului aproape în timp real.

În timp ce importăm aceste utilitare, inițializam suplimentar aplicația ExpressJS. Rețineți că primele două rânduri sunt deja scrise pentru dvs.

 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,

Cu utilitățile încărcate, serverul furnizat îi cere serverului să returneze index.html ca pagină de pornire. Rețineți că nu există niciun cod nou scris mai jos; aceasta este pur și simplu o explicație a codului sursă existent.

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

În cele din urmă, codul sursă existent indică aplicației să se lege și să asculte un port, care este 3000 în mod implicit, dacă nu este specificat altfel.

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

Odată ce ați terminat de editat, Glitch reîncarcă automat serverul. Faceți clic pe „Afișați” în stânga sus pentru a previzualiza aplicația.

Aplicația dvs. web este acum în funcțiune. În continuare, vom trimite mesaje de la client la server.

Pasul 5: Trimiteți informații de la client la server

În acest pas, vom folosi clientul pentru a inițializa o conexiune cu serverul. Clientul va informa suplimentar serverul dacă este un telefon sau un desktop. Pentru a începe, importați fișierul Javascript care va exista în curând în views/index.html .

După linia 4, includeți un nou script.

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

Pe linia 14, adăugați camera-listener la lista de proprietăți pentru entitatea cameră.

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

Apoi, navigați la public/client.js în bara laterală din stânga. Ștergeți tot codul Javascript din acest fișier. Apoi, definiți o funcție de utilitate care verifică dacă clientul este un dispozitiv mobil.

 /** * 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; };

În continuare, vom defini o serie de mesaje inițiale de schimbat cu partea serverului. Definiți un nou obiect socket.io pentru a reprezenta conexiunea clientului la server. Odată ce priza se conectează, înregistrați un mesaj pe consolă.

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

Verificați dacă dispozitivul este mobil și trimiteți informațiile corespunzătoare către server, folosind funcția emit .

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

Aceasta încheie trimiterea mesajului clientului. Acum, modificați codul serverului pentru a primi acest mesaj și a reacționa corespunzător. Deschideți fișierul server server.js .

Gestionați noile conexiuni și ascultați imediat tipul de client. La sfârșitul fișierului, adăugați următoarele.

 /** * 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'"); }); });

Din nou, previzualizați aplicația făcând clic pe „Afișați” în stânga sus. Încărcați aceeași adresă URL pe dispozitivul dvs. mobil. În terminalul dvs., veți vedea următoarele.

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

Aceasta este prima transmitere simplă a mesajelor, în care clientul nostru trimite informații înapoi către server. Închideți procesul NodeJS care rulează. Pentru ultima parte a acestui pas, clientul va trimite informațiile camerei înapoi către server. Deschide public/client.js .

La sfârșitul fișierului, includeți următoarele.

 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 }); } }); }

Salveaza si inchide. Deschideți fișierul server.js pentru a asculta acest eveniment onMove .

Adăugați următoarele, în blocul newHost al codului de socket.

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

Încă o dată, încărcați previzualizarea pe desktop și pe dispozitivul dvs. mobil. Odată ce un client mobil este conectat, serverul va începe imediat să înregistreze informațiile despre poziția și rotația camerei, trimise de la client la server. În continuare, veți implementa inversul, în care trimiteți informații de la server înapoi către client.

Pasul 6: Trimiteți informații de la server la client

În acest pas, veți trimite informațiile despre camera gazdei către toate oglinzile. Deschideți fișierul serverului principal, server.js .

Schimbați handlerul de evenimente onMove la următorul:

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

Modificatorul de broadcast asigură că serverul trimite aceste informații tuturor clienților conectați la socket, cu excepția expeditorului original. Odată ce aceste informații sunt trimise unui client, trebuie să setați camera oglinzii în consecință. Deschideți scriptul client, public/client.js .

Aici, verificați dacă clientul este un desktop. Dacă da, primiți datele de mișcare și înregistrați-vă în consecință.

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

Încărcați previzualizarea pe desktop și pe dispozitivul mobil. În browserul desktop, deschideți consola pentru dezvoltatori. Apoi, încărcați aplicația pe telefonul mobil. De îndată ce telefonul mobil încarcă aplicația, consola pentru dezvoltatori de pe desktop ar trebui să se aprindă cu poziția și rotația camerei.

Deschideți încă o dată scriptul client, la public/client.js . In final ajustam camera clientului in functie de informatiile trimise.

Modificați handlerul de evenimente de mai sus pentru evenimentul de move .

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

Încărcați aplicația pe desktop și pe telefon. Fiecare mișcare a telefonului tău este reflectată în oglinda corespunzătoare de pe desktop! Aceasta încheie partea oglindă a aplicației dvs. În calitate de utilizator de desktop, acum puteți previzualiza ceea ce vede utilizatorul dvs. mobil. Conceptele introduse în această secțiune vor fi cruciale pentru dezvoltarea ulterioară a acestui joc, pe măsură ce transformăm un joc single-player într-un joc multiplayer.

Concluzie

În acest tutorial, am programat obiecte tridimensionale și am adăugat interacțiuni simple acestor obiecte. În plus, ați creat un sistem simplu de transmitere a mesajelor între clienți și servere, pentru a realiza o previzualizare pe desktop a ceea ce văd utilizatorii dvs. de telefonie mobilă.

Aceste concepte se extind chiar și dincolo de webVR, deoarece noțiunea de geometrie și material se extinde la SceneKit pe iOS (care este legat de ARKit), Three.js (coloana vertebrală pentru Aframe) și alte biblioteci tridimensionale. Aceste blocuri simple puse împreună ne permit o flexibilitate amplă în crearea unui joc de aventură complet tip point-and-click. Mai important, ele ne permit să creăm orice joc cu o interfață bazată pe clic.

Iată câteva resurse și exemple de explorat în continuare:

  • MirrorVR
    O implementare completă a previzualizării live construită mai sus. Cu doar un singur link Javascript, adăugați o previzualizare live a oricărui model de realitate virtuală de pe mobil pe un desktop.
  • Puțin cu puțin
    O galerie de desene pentru copii și modelul de realitate virtuală corespunzător fiecărui desen.
  • Un cadru
    Exemple, documentație pentru dezvoltatori și mai multe resurse pentru dezvoltarea realității virtuale.
  • Experiențe Google Cardboard
    Experiențe pentru sala de clasă cu instrumente personalizate pentru educatori.

Data viitoare, vom construi un joc complet, folosind socket-uri web pentru a facilita comunicarea în timp real între jucători într-un joc de realitate virtuală. Simțiți-vă liber să vă împărtășiți propriile modele în comentariile de mai jos.