Cum să construiești un joc de realitate virtuală multiplayer în timp real (Partea 1)

Publicat: 2022-03-10
Rezumat rapid ↬ Realitatea virtuală este un nou mediu captivant pentru explorarea conținutului, indiferent dacă acel conținut este un film ( Life of Pi ), ​​un joc ( Beat Saber ) sau o experiență socială ( așa cum este descris în Ready Player One ). În ciuda noutății sale, VR nu necesită un set de instrumente drastic diferit pentru a proiecta - aceleași instrumente pe care le folosim pentru dezvoltarea jocurilor web, modelarea 3D și altele sunt încă aplicabile. Acest tutorial vă valorifică familiaritatea cu dezvoltarea web pentru a începe cu dezvoltarea VR.

În această serie de tutoriale, vom construi un joc de realitate virtuală multiplayer bazat pe web, în ​​care jucătorii vor trebui să colaboreze pentru a rezolva un puzzle. Vom folosi A-Frame pentru modelarea VR, MirrorVR pentru sincronizarea în timp real între dispozitive și A-Frame Low Poly pentru estetica low-poli. La sfârșitul acestui tutorial, veți avea o demonstrație online complet funcțională pe care o poate juca oricine.

Fiecare pereche de jucători primește un inel de globuri. Scopul este de a „porni” toate globurile, unde un glob este „pornit” dacă este ridicat și luminos. Un orb este „off” dacă este mai jos și slab. Cu toate acestea, anumite globuri „dominante” își afectează vecinii: dacă schimbă starea, vecinii săi schimbă și starea. Doar jucătorul 2 poate controla globurile dominante, în timp ce doar jucătorul 1 poate controla globurile nedominante. Acest lucru îi obligă pe ambii jucători să colaboreze pentru a rezolva puzzle-ul. În această primă parte a tutorialului, vom construi mediul și vom adăuga elementele de design pentru jocul nostru VR.

Cei șapte pași din acest tutorial sunt grupați în trei secțiuni:

  1. Configurarea scenei (Pașii 1–2)
  2. Crearea globurilor (Pașii 3–5)
  3. Efectuarea Orbs interactive (Pașii 6-7)
Mai multe după săritură! Continuați să citiți mai jos ↓

Această primă parte se va încheia cu un orb pe care se poate face clic care se pornește și se oprește (așa cum este imaginea de mai jos). Veți folosi A-Frame VR și mai multe extensii A-Frame.

(Previzualizare mare)

Configurarea Scenei

1. Să mergem cu o scenă de bază

Pentru a începe, să aruncăm o privire la modul în care putem configura o scenă simplă cu un teren:

Crearea unei scene simple
Crearea unei scene simple (previzualizare mare)

Primele trei instrucțiuni de mai jos sunt extrase din articolul meu anterior. Veți începe prin a configura un site web cu o singură pagină HTML statică. Acest lucru vă permite să codificați de pe desktop și să îl implementați 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, faceți următoarele:

  1. Faceți clic pe „Proiect nou” în dreapta sus,
  2. Faceți clic pe „hello-webpage” în meniul drop-down,
  3. Apoi, faceți clic pe index.html în bara laterală din stânga. Ne vom referi la asta drept „editorul tău”.

Acum ar trebui să vedeți următorul ecran Glitch cu un fișier HTML implicit.

Proiect Glitch: fișierul index.html
Proiect Glitch: fișierul index.html (previzualizare mare)

Ca și în tutorialul legat de mai sus, începeți prin a șterge tot codul existent din fișierul index.html curent. Apoi, tastați următoarele pentru un proiect webVR de bază, folosind A-Frame VR. Acest lucru creează o scenă goală utilizând iluminarea și camera implicite 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>

Ridicați camera la înălțimea în picioare. Conform recomandărilor A-Frame VR (problema Github), împachetați camera cu o nouă entitate și mutați entitatea părinte în loc de camera direct. Între etichetele a-scene pe rândurile 8 și 9, adăugați următoarele.

 <!-- Camera! --> <a-entity position="0 3 0"> <a-camera wasd-controls look-controls></a-camera> </a-entity>

Apoi, adăugați o casetă mare pentru a indica pământul, folosind a-box . Plasați-l direct sub camera dvs. din instrucțiunile anterioare.

 <!-- Action! --> <a-box shadow width="75" height="0.1" depth="75" position="0 -1 0" color="#222"></a-box>

Fișierul dvs. index.html ar trebui acum să se potrivească exact cu următoarele. Puteți găsi codul sursă complet aici, pe 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>

Aceasta se încheie configurarea. În continuare, vom personaliza iluminarea pentru o atmosferă mai misterioasă.

2. Adăugați atmosferă

În acest pas, vom configura ceața și iluminarea personalizată.

O previzualizare a unei scene simple cu o dispoziție întunecată
O previzualizare a unei scene simple cu o dispoziție întunecată (Previzualizare mare)

Adăugați o ceață, care va întuneca obiectele aflate la distanță pentru noi. Modificați eticheta a-scene pe linia 8. Aici, vom adăuga o ceață întunecată care ascunde rapid marginile pământului, dând efectul unui orizont îndepărtat.

 <a-scene fog="type: linear; color: #111; near:10; far:15"></a-scene>

Gri închis #111 se estompează liniar de la o distanță de 10 la o distanță de 15. Toate obiectele aflate la mai mult de 15 unități sunt complet ascunse și toate obiectele aflate la mai puțin de 10 unități sunt complet vizibile. Orice obiect între ele este parțial ascuns.

Adăugați o lumină ambientală pentru a lumina obiectele din joc și lumină unidirecțională pentru a accentua suprafețele reflectorizante pe care le veți adăuga mai târziu. Plasați-l direct după eticheta a-scene pe care ați modificat-o în instrucțiunea anterioară.

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

Direct sub lumini din instrucțiunile anterioare, adăugați un cer întunecat. Observați că gri închis #111 se potrivește cu cea din ceața îndepărtată.

 <a-sky color="#111"></a-sky>

Aceasta încheie modificări de bază ale stării de spirit și, mai larg, configurarea scenei. Verificați dacă codul dvs. se potrivește exact cu codul sursă pentru Pasul 2 de pe Github. În continuare, vom adăuga un glob low-poly și vom începe să personalizăm estetica globului.

Crearea Orbs

3. Creați un Orb Low-Poly

În acest pas, vom crea un glob rotativ, reflectorizant, așa cum este imaginea de mai jos. Globul este compus din două sfere stilizate low-poli cu câteva trucuri pentru a sugera material reflectorizant.

Orb rotativ, reflectorizant
(Previzualizare mare)

Începeți prin a importa biblioteca low-poly din eticheta head . Introduceți următoarele între rândurile 4 și 5.

 <script src="https://cdn.jsdelivr.net/gh/alvinwan/[email protected]/dist/aframe-low-poly.min.js"></script>

Creați un carusel, un ambalaj și un container orb. carousel va conține mai multe globuri, wrapper ne va permite să rotim toate globurile în jurul unei axe centrale fără a roti fiecare glob individual, iar container va conține - după cum sugerează și numele - toate componentele globului.

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

În interiorul recipientului globului, adăugați globul în sine: o sferă este ușor translucidă și decalată, iar cealaltă este complet solidă. Cele două combinate imită suprafețele reflectorizante.

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

În cele din urmă, rotiți sfera la nesfârșit adăugând următoarea etichetă a-animation imediat după lp-sphere interiorul entității .orb în ultima instrucțiune.

 <a-animation attribute="rotation" repeat="indefinite" from="0 0 0" to="0 360 0" dur="5000"></a-animation>

Codul dvs. sursă pentru ambalajele orb și orb-ul în sine ar trebui să se potrivească exact cu următoarele.

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

Verificați dacă codul dvs. sursă se potrivește cu codul sursă complet pentru pasul 3 pe Github. Previzualizarea dvs. ar trebui să se potrivească acum cu următoarele.

Orb rotativ, reflectorizant
(Previzualizare mare)

În continuare, vom adăuga mai multă lumină globului pentru o nuanță aurie.

4. Luminează Orb

În acest pas, vom adăuga două lumini, una colorată și una albă. Acest lucru produce următorul efect.

Orb aprins cu lumini punctiforme
(Previzualizare mare)

Începeți prin a adăuga lumina albă pentru a ilumina obiectul de jos. Vom folosi o lumină punctuală. Direct înainte de #orb0 , dar în cadrul #container-orb0 , adăugați următorul punct luminos de compensare.

 <a-entity position="-2 -1 0"> <a-light distance="8" type="point" color="#FFF" intensity="0.8"></a-light> </a-entity>

În previzualizarea dvs., veți vedea următoarele.

Orb aprins cu lumină punct alb
(Previzualizare mare)

În mod implicit, luminile nu se diminuează cu distanța. Adăugând distance="8" , ne asigurăm că lumina scade complet cu o distanță de 8 unități, pentru a împiedica lumina punctuală să ilumineze întreaga scenă. Apoi, adăugați lumina aurie. Adăugați următoarele direct deasupra ultimei lumini.

 <a-light class="light-orb" distance="8" type="point" color="#f90" intensity="1"></a-light>

Verificați dacă codul dvs. se potrivește exact cu codul sursă pentru pasul 4. Previzualizarea dvs. se va potrivi acum cu următoarele.

Orb aprins cu lumini punctiforme
(Previzualizare mare)

Apoi, veți face modificarea estetică finală a globului și veți adăuga inele rotative.

5. Adăugați inele

În acest pas, veți produce globul final, așa cum se arată mai jos.

Glob auriu cu mai multe inele
(Previzualizare mare)

Adăugați un inel în #container-orb0 direct înainte de #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>

Observați că inelul în sine nu conține culoare, deoarece culoarea va fi impregnată de lumina punctuală în pasul anterior. În plus, material="side:double" este important deoarece, fără el, partea din spate a inelului nu ar fi redată; aceasta înseamnă că inelul ar dispărea pentru jumătate din rotație.

Cu toate acestea, previzualizarea doar cu codul de mai sus nu va arăta diferit. Acest lucru se datorează faptului că inelul este în prezent perpendicular pe ecran. Astfel, doar „partea” inelului (care are 0 grosime) este vizibilă. Plasați următoarea animație între etichetele a-ring din instrucțiunea anterioară.

 <a-animation attribute="rotation" easing="linear" repeat="indefinite" from="0 0 0" to="0 360 0" dur="8000"></a-animation>

Previzualizarea dvs. ar trebui să se potrivească acum cu următoarele:

Orb de aur cu inel
(Previzualizare mare)

Creați un număr variabil de inele cu diferite axe de rotație, viteze și dimensiuni. Puteți folosi următoarele exemple de inele. Orice inele noi ar trebui să fie plasate sub ultimul 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>

Previzualizarea dvs. se va potrivi acum cu următoarele.

Glob auriu cu mai multe inele
(Previzualizare mare)

Verificați dacă codul dvs. se potrivește cu codul sursă pentru pasul 5 pe Github. Aceasta încheie decorul pentru glob. Odată cu orb-ul terminat, vom adăuga în continuare interactivitate orb-ului. În pasul următor, vom adăuga în mod specific un cursor vizibil cu o animație de clic atunci când îndreptăm spre obiecte pe care se poate face clic.

Facerea Orbs interactiv

6. Adăugați un cursor

În acest pas, vom adăuga un cursor alb care poate declanșa obiecte pe care se poate face clic. Cursorul este ilustrat mai jos.

făcând clic pe orb
(Previzualizare mare)

În eticheta a-camera , adăugați următoarea entitate. Atributul fuse permite acestei entități abilitatea de a declanșa evenimente de clic. Atributul raycaster determină cât de des și cât de departe se verifică obiectele pe care se poate face clic. Atributul objects acceptă un selector pentru a determina ce entități se pot face clic. În acest caz, toate obiectele din clasa pe care se poate face clickable sunt pe care se poate face clic.

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

Apoi, adăugați animația cursorului și un inel suplimentar pentru estetică. Plasați următoarele în interiorul obiectului cursor entitate de mai sus. Aceasta adaugă animație obiectului cursor, astfel încât clicurile să fie vizibile.

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

Apoi, adăugați clasa pe care se clickable la #orb0 pentru a se potrivi cu următoarele.

 <a-entity class="orb clickable" data->

Verificați dacă codul dvs. se potrivește cu codul sursă pentru Pasul 6 pe Github. În previzualizare, trageți cursorul de pe ele pe orb pentru a vedea animația de clic în acțiune. Aceasta este imaginea de mai jos.

făcând clic pe orb
(Previzualizare mare)

Rețineți că atributul pe care se poate face clic a fost adăugat la orb în sine și nu la containerul orb. Acest lucru este pentru a preveni inelele să devină obiecte pe care se poate face clic. În acest fel, utilizatorul trebuie să facă clic pe sferele care alcătuiesc orbul în sine.

În pasul nostru final pentru această parte, veți adăuga animație pentru a controla stările de pornire și oprire pentru orb.

7. Adăugați State Orb

În acest pas, veți anima globul în și din starea oprită la clic. Aceasta este imaginea de mai jos.

Orb interactiv care răspunde la clicuri
(Previzualizare mare)

Pentru a începe, vei micșora și vei coborî globul la pământ. Adăugați etichete a-animation la #container-orb0 imediat după #orb0 . Ambele animații sunt declanșate printr-un clic și au aceeași funcție ease-elastic pentru o ușoară săritură.

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

Pentru a sublinia și mai mult starea oprită, vom elimina lumina punctului de aur când globul este stins. Cu toate acestea, luminile globului sunt plasate în afara obiectului globului. Astfel, evenimentul clic nu este transmis luminilor atunci când se face clic pe orb. Pentru a evita această problemă, vom folosi ceva Javascript ușor pentru a transmite evenimentul de clic la lumină. Plasați următoarea etichetă de animație în #light-orb0 . Lumina este declanșată de un eveniment de switch personalizat.

 <a-animation class="animation-intensity" begin="switch" attribute="intensity" from="0" to="1" direction="alternate"></a-animation>

Apoi, adăugați următorul ascultător de evenimente clic la #container-orb0 . Acest lucru va transmite clicurile către luminile orb.

 <a-entity ...>

Verificați dacă codul dvs. se potrivește cu codul sursă pentru Pasul 7 pe Github. În cele din urmă, trageți în sus previzualizarea și mutați cursorul pe și în afara orbului pentru a comuta între stările dezactivate și activate. Aceasta este imaginea de mai jos.

Orb interactiv care răspunde la clicuri
(Previzualizare mare)

Aceasta încheie interactivitatea globului. Jucătorul poate acum să pornească și să dezactiveze orburile după bunul plac, cu stări de activare și dezactivare autoexplicative.

Concluzie

În acest tutorial, ați creat un orb simplu cu stări pornit și oprit, care poate fi comutat printr-un clic de cursor compatibil cu căștile VR. Cu o serie de tehnici de iluminare și animații diferite, ați reușit să distingeți între cele două stări. Aceasta încheie elementele de proiectare a realității virtuale pentru sfere. În următoarea parte a tutorialului, vom popula globurile în mod dinamic, vom adăuga mecanisme de joc și vom configura un protocol de comunicare între o pereche de jucători.