Jak zbudować model wirtualnej rzeczywistości z podglądem w czasie rzeczywistym na różnych urządzeniach?
Opublikowany: 2022-03-10Rzeczywistość wirtualna (VR) to doświadczenie oparte na środowisku generowanym komputerowo; wiele różnych produktów VR pojawia się na pierwszych stronach gazet, a ich zastosowania są bardzo szerokie: podczas zimowych igrzysk olimpijskich zespół z USA wykorzystywał wirtualną rzeczywistość do treningu sportowego; chirurdzy eksperymentują z wirtualną rzeczywistością w celu szkolenia medycznego; a najczęściej rzeczywistość wirtualna jest stosowana w grach.
Skupimy się na ostatniej kategorii aplikacji, a w szczególności skupimy się na grach przygodowych typu „wskaż i kliknij” . Takie gry to zwykła klasa gier; celem jest wskazywanie i klikanie obiektów na scenie, aby zakończyć układankę. W tym samouczku zbudujemy prostą wersję takiej gry, ale w wirtualnej rzeczywistości. Służy jako wprowadzenie do programowania w trzech wymiarach i jest samodzielnym przewodnikiem wprowadzającym do wdrażania modelu rzeczywistości wirtualnej w Internecie. Będziesz budować z webVR, frameworkiem, który daje podwójną przewagę — użytkownicy mogą grać w twoją grę w VR, a użytkownicy bez gogli VR mogą nadal grać w twoją grę na telefonie lub komputerze.
Programowanie dla wirtualnej rzeczywistości
W dzisiejszych czasach każdy programista może tworzyć treści dla VR. W lepszym zrozumieniu rozwoju VR może pomóc praca nad projektem demonstracyjnym. Przeczytaj powiązany artykuł →
W drugiej połowie tego samouczka zbudujesz „lustro” na swój pulpit. Oznacza to, że wszystkie ruchy wykonywane przez gracza na urządzeniu mobilnym będą odzwierciedlone w podglądzie na pulpicie. Pozwala to zobaczyć, co widzi gracz, co pozwala na udzielanie wskazówek, nagrywanie gry lub po prostu zapewnia rozrywkę gościom.
Warunki wstępne
Aby rozpocząć, będziesz potrzebować następujących elementów. W drugiej połowie tego samouczka będziesz potrzebować systemu Mac OSX. Chociaż kod może dotyczyć dowolnej platformy, poniższe instrukcje instalacji zależności dotyczą komputerów Mac.
- dostęp do Internetu, w szczególności do glitch.com;
- Gogle wirtualnej rzeczywistości (opcjonalne, zalecane). Używam Google Cardboard, który jest oferowany w cenie 15 USD za sztukę.
Krok 1: Konfiguracja modelu wirtualnej rzeczywistości (VR)
W tym kroku skonfigurujemy witrynę internetową z pojedynczą statyczną stroną HTML. Dzięki temu możemy kodować z Twojego komputera i automatycznie wdrażać w sieci. Wdrożoną stronę internetową można następnie załadować na telefon komórkowy i umieścić w goglach VR. Alternatywnie wdrożoną witrynę można załadować za pomocą samodzielnego zestawu słuchawkowego VR. Zacznij od przejścia na glitch.com. Następnie,
- Kliknij „Nowy projekt” w prawym górnym rogu.
- Kliknij „hello-express” w menu rozwijanym.
Następnie kliknij views/index.html na lewym pasku bocznym. Będziemy nazywać to „redaktorem”.
Aby wyświetlić podgląd strony internetowej, kliknij „Podgląd” w lewym górnym rogu. Nazywamy to podglądem . Pamiętaj, że wszelkie zmiany w edytorze zostaną automatycznie odzwierciedlone w tym podglądzie, z wyłączeniem błędów lub nieobsługiwanych przeglądarek.
Wróć do edytora i zastąp aktualny kod HTML następującym szablonem dla modelu 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>
Nawiguj, zobacz następujące.
Aby wyświetlić podgląd na goglach VR, użyj adresu URL na omnibarze. Na powyższym obrazku adres URL to https://point-and-click-vr-game.glitch.me/
. Twoje środowisko pracy jest teraz skonfigurowane; możesz udostępnić ten adres URL rodzinie i znajomym. W kolejnym kroku stworzysz model wirtualnej rzeczywistości.
Krok 2: Zbuduj model drzewa
Utworzysz teraz drzewo, używając prymitywów z aframe.io. Są to standardowe obiekty, które firma Aframe zaprogramowała w celu ułatwienia użytkowania. W szczególności Aframe odnosi się do obiektów jako jednostek . Istnieją trzy koncepcje, odnoszące się do wszystkich podmiotów, wokół których organizujemy naszą dyskusję:
- Geometria i materiał,
- Osie transformacji,
- Transformacje względne.
Po pierwsze, geometria i materiał to dwa bloki budulcowe wszystkich trójwymiarowych obiektów w kodzie. Geometria definiuje „kształt” — sześcian, kulę, piramidę i tak dalej. Materiał określa statyczne właściwości kształtu, takie jak kolor, odblaskowość, chropowatość.
Aframe upraszcza tę koncepcję, definiując prymitywne elementy, takie jak <a-box>
, <a-sphere>
, <a-cylinder>
i wiele innych, aby uprościć specyfikację geometrii i jej materiału. Zacznij od zdefiniowania zielonej kuli. W wierszu 19 w kodzie, zaraz po <!-- start code here -->
, dodaj następujący kod.
<!-- start code here --> <a-sphere color="green" radius="0.5"></a-sphere> <!-- new line --> <!-- end code here -->
Po drugie, istnieją trzy osie, wzdłuż których można przekształcić nasz obiekt. Oś x
biegnie poziomo, gdzie wartości x rosną, gdy poruszamy się w prawo. Oś y
biegnie pionowo, gdzie wartości y rosną wraz z ruchem w górę. Oś z
wybiega z ekranu, gdzie wartości z rosną, gdy zbliżamy się do Ciebie. Możemy tłumaczyć, obracać lub skalować elementy wzdłuż tych trzech osi.
Na przykład, aby przetłumaczyć obiekt na „prawo”, zwiększamy jego wartość x. Aby obrócić przedmiot taki jak blat, obracamy go wzdłuż osi y. Zmodyfikuj linię 19, aby przesunąć kulę „w górę” — oznacza to, że musisz zwiększyć wartość y kuli. Zauważ, że wszystkie przekształcenia są określone jako <x> <y> <z>
, co oznacza, że aby zwiększyć jego wartość y, musisz zwiększyć drugą wartość. Domyślnie wszystkie obiekty znajdują się na pozycji 0, 0, 0. Dodaj specyfikację position
poniżej.
<!-- start code here --> <a-sphere color="green" radius="0.5" position="0 1 0"></a-sphere> <!-- edited line --> <!-- end code here -->
Po trzecie, wszystkie przekształcenia odnoszą się do jego rodzica. Aby dodać pień do swojego drzewa, dodaj cylinder wewnątrz kuli powyżej. Gwarantuje to, że pozycja twojego tułowia jest zależna od pozycji kuli. Zasadniczo utrzymuje to twoje drzewo jako jedną jednostkę. Dodaj encję <a-cylinder>
między tagami <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>
Aby zrobić ten bezdrzewny szkielet, dodaj więcej liści, w postaci dwóch kolejnych zielonych kul.
<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>
Wróć do podglądu, a zobaczysz następujące drzewo:
Załaduj ponownie podgląd strony internetowej na goglach VR i sprawdź swoje nowe drzewo. W następnej sekcji uczynimy to drzewo interaktywnym.
Krok 3: Dodaj interakcję kliknięcia do modelu
Aby uczynić encję interaktywną, musisz:
- Dodaj animację,
- Niech ta animacja uruchamia się po kliknięciu.
Ponieważ użytkownik końcowy korzysta z zestawu słuchawkowego rzeczywistości wirtualnej, kliknięcie jest równoznaczne z wpatrywaniem się: innymi słowy, wpatrywanie się w obiekt, aby go „kliknąć”. Aby wprowadzić te zmiany, zaczniesz od kursora. Zmień definicję aparatu, zastępując wiersz 13 następującym.
<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>
Powyższe dodaje kursor, który może wywołać akcję kliknięcia. Zwróć uwagę na objects: .clickable
. Oznacza to, że wszystkie obiekty z klasą „klikalne” wywołają animację i otrzymają polecenie „kliknij” tam, gdzie to konieczne. Dodasz również animację do kursora kliknięcia, aby użytkownicy wiedzieli, kiedy kursor wywoła kliknięcie. W tym przypadku kursor będzie się powoli kurczył, gdy wskazuje obiekt, który można kliknąć, przyciągając po sekundzie, aby wskazać, że obiekt został kliknięty. Zastąp komentarz <!-- add animation here -->
następującym kodem:
<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>
Przesuń drzewo w prawo o 2 jednostki i dodaj klasę „klikalną” do drzewa, modyfikując wiersz 29, aby odpowiadał następującym.
<a-sphere color="green" radius="0.5" position="2 0.75 0" class="clickable">
Następnie będziesz:
- Określ animację,
- Uruchom animację jednym kliknięciem.
Dzięki łatwej w użyciu encji animacji Aframe, oba kroki można wykonać szybko po sobie.
Dodaj <a-animation>
w wierszu 33, zaraz po <a-cylinder>
, ale przed końcem </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>
Powyższe właściwości określają szereg konfiguracji animacji. Animacja:
- Jest wyzwalany przez zdarzenie
click
- Modyfikuje
position
drzewa - Rozpoczyna się od pozycji wyjściowej
2 0.75 0
- Kończy się
2.2 0.75 0
(przesunięcie 0,2 jednostki w prawo) - Animacje podczas podróży do i z miejsca docelowego
- Zamienia animację między podróżowaniem do i z miejsca docelowego
- Powtarza tę animację raz. Oznacza to, że obiekt jest animowany w sumie dwukrotnie — raz do celu i raz z powrotem do pierwotnej pozycji.
Na koniec przejdź do podglądu i przeciągnij z kursora do drzewa. Gdy czarny okrąg spocznie na drzewie, drzewo przesunie się w prawo iz powrotem.
To kończy podstawy potrzebne do zbudowania gry przygodowej typu „wskaż i kliknij” w wirtualnej rzeczywistości. Aby wyświetlić i zagrać w bardziej kompletną wersję tej gry, zobacz następującą krótką scenkę. Misją jest otwarcie bramy i ukrycie drzewa za bramą, klikając różne obiekty w scenie.
Następnie konfigurujemy prosty serwer nodeJS do obsługi naszego statycznego demo.
Krok 4: Skonfiguruj serwer NodeJS
W tym kroku skonfigurujemy podstawowy, funkcjonalny serwer nodeJS, który obsługuje Twój istniejący model VR. Na lewym pasku bocznym edytora wybierz package.json
.
Zacznij od usunięcia wierszy 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",
Zmień nazwę na mirrorvr
.
{ "name": "mirrorvr", // change me "version": "0.0.1", ...
W obszarze dependencies
dodaj socket.io
.
"dependencies": { "express": "^4.16.3", "socketio": "^1.0.0", },
Zaktualizuj adres URL repozytorium, aby pasował do aktualnej usterki. Przykładowy projekt usterki nosi nazwę point-and-click-vr-game
. Zastąp to nazwą swojego projektu usterki.
"repository": { "url": "https://glitch.com/edit/#!/point-and-click-vr-game" },
Na koniec zmień tag "glitch"
na "vr"
.
"keywords": [ "node", "vr", // change me "express" ]
Dokładnie sprawdź, czy Twój package.json
odpowiada teraz następującym.
{ "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" ] }
Dokładnie sprawdź, czy kod z poprzednich części jest zgodny z następującym w 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>
Zmodyfikuj istniejący server.js
.
Zacznij od zaimportowania kilku narzędzi NodeJS.
- Wyrazić
To jest struktura internetowa, której użyjemy do uruchomienia serwera. - http
Pozwala nam to na uruchomienie demona, nasłuchującego aktywności na różnych portach. - gniazdo.io
Implementacja gniazd, która pozwala nam komunikować się między stroną klienta a stroną serwera w czasie niemal rzeczywistym.
Podczas importu tych narzędzi dodatkowo inicjujemy aplikację ExpressJS. Zauważ, że pierwsze dwie linijki są już dla Ciebie napisane.
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,
Po załadowaniu narzędzi dostarczony serwer następnie instruuje serwer, aby zwrócił index.html
jako stronę domową. Zauważ, że poniżej nie ma nowego kodu; jest to po prostu wyjaśnienie istniejącego kodu źródłowego.
// https://expressjs.com/en/starter/basic-routing.html app.get('/', function(request, response) { response.sendFile(__dirname + '/views/index.html'); });
Na koniec istniejący kod źródłowy instruuje aplikację, aby powiązała się i nasłuchiwała portu, który domyślnie ma wartość 3000, chyba że określono inaczej.
// listen for requests :) var listener = app.listen(process.env.PORT, function() { console.log('Your app is listening on port ' + listener.address().port); });
Po zakończeniu edycji Glitch automatycznie przeładuje serwer. Kliknij „Pokaż” w lewym górnym rogu, aby wyświetlić podgląd aplikacji.
Twoja aplikacja internetowa jest już uruchomiona. Następnie wyślemy wiadomości od klienta na serwer.
Krok 5: Wyślij informacje z klienta do serwera
W tym kroku użyjemy klienta do zainicjowania połączenia z serwerem. Klient dodatkowo poinformuje serwer, czy jest to telefon czy komputer stacjonarny. Aby rozpocząć, zaimportuj wkrótce istniejący plik JavaScript do pliku views/index.html
.
Po wierszu 4 dołącz nowy skrypt.
<script src="/client.js" type="text/javascript"></script>
W wierszu 14. dodaj camera-listener
do listy właściwości jednostki camera.
<a-entity camera-listener camera look-controls...> ... </a-entity>
Następnie przejdź do public/client.js
na lewym pasku bocznym. Usuń cały kod JavaScript z tego pliku. Następnie zdefiniuj funkcję narzędziową, która sprawdza, czy klient jest urządzeniem mobilnym.
/** * 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; };
Następnie zdefiniujemy serię początkowych wiadomości do wymiany ze stroną serwera. Zdefiniuj nowy obiekt socket.io reprezentujący połączenie klienta z serwerem. Gdy gniazdo połączy się, zarejestruj komunikat w konsoli.
var socket = io(); socket.on('connect', function() { console.log(' * Connection established'); });
Sprawdź, czy urządzenie jest mobilne i wyślij odpowiednią informację na serwer, korzystając z funkcji emit
.
if (mobilecheck()) { socket.emit('newHost'); } else { socket.emit('newMirror'); }
Na tym kończy się wysyłanie wiadomości do klienta. Teraz zmień kod serwera, aby otrzymać tę wiadomość i odpowiednio zareagować. Otwórz plik server.js
serwera.
Obsługuj nowe połączenia i natychmiast nasłuchuj typu klienta. Na końcu pliku dodaj następujące.
/** * 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'"); }); });
Ponownie wyświetl podgląd aplikacji, klikając „Pokaż” w lewym górnym rogu. Załaduj ten sam adres URL na swoim urządzeniu mobilnym. W swoim terminalu zobaczysz następujące elementy.
listening on *: 3000 * Participant registered as 'host' * Participant registered as 'mirror'
Jest to pierwsze proste przekazywanie wiadomości, w którym nasz klient wysyła informacje z powrotem do serwera. Zakończ działający proces NodeJS. W końcowej części tego kroku klient wyśle informacje o kamerze z powrotem na serwer. Otwórz public/client.js
.
Na samym końcu pliku dołącz następujące elementy.
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 }); } }); }
Zapisz i zamknij. Otwórz plik serwera server.js
, aby nasłuchiwać tego zdarzenia onMove
.
Dodaj następujące elementy w bloku newHost
kodu gniazda.
socket.on('newHost', function() { console.log(" * Participant registered as 'host'"); /* start new code */ socket.on('onMove', function(data) { console.log(data); }); /* end new code */ });
Ponownie wczytaj podgląd na pulpicie i urządzeniu mobilnym. Po podłączeniu klienta mobilnego serwer natychmiast rozpocznie rejestrowanie informacji o położeniu i obrocie kamery, przesyłanych od klienta do serwera. Następnie zaimplementujesz odwrotną stronę, w której informacje z serwera przesyłasz z powrotem do klienta.
Krok 6: Wyślij informacje z serwera do klienta
W tym kroku wyślesz informacje o kamerze hosta do wszystkich serwerów lustrzanych. Otwórz główny plik serwera, server.js
.
Zmień procedurę obsługi zdarzeń onMove
na następującą:
socket.on('onMove', function(data) { console.log(data); // delete me socket.broadcast.emit('move', data) });
Modyfikator broadcast
zapewnia, że serwer wyśle te informacje do wszystkich klientów podłączonych do gniazda, z wyjątkiem oryginalnego nadawcy. Po wysłaniu tych informacji do klienta należy odpowiednio ustawić kamerę w lustrze. Otwórz skrypt klienta public/client.js
.
Tutaj sprawdź, czy klient jest komputerem stacjonarnym. Jeśli tak, odbierz dane przeniesienia i odpowiednio zarejestruj.
if (!mobilecheck()) { socket.on('move', function(data) { console.log(data); }); }
Załaduj podgląd na pulpicie i urządzeniu mobilnym. W przeglądarce na komputerze otwórz konsolę programisty. Następnie załaduj aplikację na swój telefon komórkowy. Gdy tylko telefon komórkowy załaduje aplikację, konsola programisty na pulpicie powinna zaświecić się z pozycją i obrotem aparatu.
Otwórz skrypt klienta jeszcze raz, w public/client.js
. W końcu dostosowujemy kamerę klienta w zależności od przesłanych informacji.
Zmień procedurę obsługi zdarzeń powyżej dla zdarzenia move
.
socket.on('move', function(data) { /* start new code */ camera.setAttribute('rotation', data["rotation"]); camera.setAttribute('position', data["position"]); /* end new code */ });
Załaduj aplikację na komputer i telefon. Każdy ruch Twojego telefonu odbija się w odpowiednim lustrze na Twoim pulpicie! Na tym kończy się lustrzana część Twojej aplikacji. Jako użytkownik komputera stacjonarnego możesz teraz wyświetlić podgląd tego, co widzi Twój użytkownik mobilny. Koncepcje przedstawione w tej sekcji będą kluczowe dla dalszego rozwoju tej gry, ponieważ przekształcamy grę jednoosobową w grę wieloosobową.
Wniosek
W tym samouczku zaprogramowaliśmy obiekty trójwymiarowe i dodaliśmy do nich proste interakcje. Dodatkowo zbudowałeś prosty system przekazywania wiadomości między klientami a serwerami, aby uzyskać podgląd na pulpicie tego, co widzą użytkownicy mobilni.
Te koncepcje wykraczają nawet poza webVR, ponieważ pojęcie geometrii i materiału rozciąga się na SceneKit na iOS (który jest powiązany z ARKit), Three.js (szkielet dla Aframe) i inne trójwymiarowe biblioteki. Te proste klocki połączone razem pozwalają nam na dużą elastyczność w tworzeniu pełnoprawnej gry przygodowej typu „wskaż i kliknij”. Co ważniejsze, pozwalają nam stworzyć dowolną grę z interfejsem opartym na kliknięciach.
Oto kilka zasobów i przykładów do dalszego zbadania:
- LustroVR
Pełnoprawna implementacja powyższego podglądu na żywo. Wystarczy jeden link JavaScript, aby dodać podgląd na żywo dowolnego modelu rzeczywistości wirtualnej na urządzeniu mobilnym do komputera. - Kawałek po kawałku
Galeria rysunków dzieci i odpowiadający im model wirtualnej rzeczywistości dla każdego rysunku. - Ramka
Przykłady, dokumentacja dla programistów i więcej zasobów do tworzenia wirtualnej rzeczywistości. - Funkcje Google Cardboard
Doświadczenia w klasie z niestandardowymi narzędziami dla nauczycieli.
Następnym razem zbudujemy kompletną grę, używając gniazd sieciowych, aby ułatwić komunikację w czasie rzeczywistym między graczami w grze wirtualnej rzeczywistości. Zapraszam do dzielenia się własnymi modelami w komentarzach poniżej.