So erstellen Sie ein Echtzeit-Multiplayer-Virtual-Reality-Spiel (Teil 1)

Veröffentlicht: 2022-03-10
Kurze Zusammenfassung ↬ Virtuelle Realität ist ein neues immersives Medium zum Erkunden von Inhalten, unabhängig davon, ob es sich bei diesen Inhalten um einen Film ( Life of Pi ), ​​ein Spiel ( Beat Sabre ) oder ein soziales Erlebnis (wie in Ready Player One dargestellt) handelt. Trotz seiner Neuheit erfordert VR kein grundlegend anderes Toolset für das Design – die gleichen Tools, die wir für die Entwicklung von Webspielen, die 3D-Modellierung und andere verwenden, sind alle immer noch anwendbar. Dieses Tutorial nutzt Ihre Vertrautheit mit der Webentwicklung, um mit der VR-Entwicklung zu beginnen.

In dieser Tutorial-Serie erstellen wir ein webbasiertes Multiplayer-Virtual-Reality-Spiel, in dem die Spieler zusammenarbeiten müssen, um ein Rätsel zu lösen. Wir werden A-Frame für die VR-Modellierung, MirrorVR für die geräteübergreifende Echtzeitsynchronisierung und A-Frame Low Poly für eine Low-Poly-Ästhetik verwenden. Am Ende dieses Tutorials haben Sie online eine voll funktionsfähige Demo, die jeder spielen kann.

Jedes Spielerpaar erhält einen Kugelring. Das Ziel ist es, alle Kugeln „einzuschalten“, wobei eine Kugel „eingeschaltet“ ist, wenn sie erhöht und hell ist. Eine Kugel ist „aus“, wenn sie niedriger und schwach ist. Bestimmte „dominante“ Orbs wirken sich jedoch auf ihre Nachbarn aus: Wenn sie den Zustand wechseln, wechseln auch ihre Nachbarn den Zustand. Nur Spieler 2 kann die dominanten Kugeln kontrollieren, während nur Spieler 1 nicht dominante Kugeln kontrollieren kann. Dies zwingt beide Spieler, zusammenzuarbeiten, um das Rätsel zu lösen. In diesem ersten Teil des Tutorials werden wir die Umgebung erstellen und die Designelemente für unser VR-Spiel hinzufügen.

Die sieben Schritte in diesem Tutorial sind in drei Abschnitte unterteilt:

  1. Einrichten der Szene (Schritte 1–2)
  2. Erstellen der Kugeln (Schritte 3–5)
  3. The Orbs interaktiv machen (Schritte 6–7)
Mehr nach dem Sprung! Lesen Sie unten weiter ↓

Dieser erste Teil endet mit einer anklickbaren Kugel, die sich ein- und ausschaltet (wie unten abgebildet). Sie werden A-Frame VR und mehrere A-Frame-Erweiterungen verwenden.

(Große Vorschau)

Einrichten der Szene

1. Beginnen wir mit einer einfachen Szene

Schauen wir uns zunächst an, wie wir eine einfache Szene mit einem Boden einrichten können:

Erstellen einer einfachen Szene
Erstellen einer einfachen Szene (große Vorschau)

Die ersten drei Anweisungen unten sind Auszüge aus meinem vorherigen Artikel. Sie beginnen mit der Einrichtung einer Website mit einer einzigen statischen HTML-Seite. Auf diese Weise können Sie von Ihrem Desktop aus codieren und automatisch im Web bereitstellen. Die bereitgestellte Website kann dann auf Ihr Mobiltelefon geladen und in einem VR-Headset platziert werden. Alternativ kann die bereitgestellte Website von einem eigenständigen VR-Headset geladen werden.

Beginnen Sie, indem Sie zu glitch.com navigieren. Gehen Sie dann wie folgt vor:

  1. Klicken Sie oben rechts auf „Neues Projekt“,
  2. Klicken Sie im Drop-down-Menü auf „hello-webpage“,
  3. Klicken Sie anschließend in der linken Seitenleiste auf index.html . Wir bezeichnen dies als Ihren „Redakteur“.

Sie sollten jetzt den folgenden Glitch-Bildschirm mit einer Standard-HTML-Datei sehen.

Glitch-Projekt: die index.html-Datei
Glitch-Projekt: die index.html-Datei (große Vorschau)

Beginnen Sie wie beim oben verlinkten Tutorial damit, den gesamten vorhandenen Code in der aktuellen index.html -Datei zu löschen. Geben Sie dann Folgendes für ein einfaches WebVR-Projekt mit A-Frame VR ein. Dadurch wird eine leere Szene erstellt, indem die Standardbeleuchtung und -kamera von A-Frame verwendet werden.

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

Heben Sie die Kamera auf Stehhöhe an. Wickeln Sie die Kamera gemäß den A-Frame-VR-Empfehlungen (Github-Problem) mit einer neuen Entität ein und verschieben Sie die übergeordnete Entität anstelle der Kamera direkt. Fügen Sie zwischen Ihren a-scene Tags in den Zeilen 8 und 9 Folgendes hinzu.

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

Fügen Sie als Nächstes ein großes Kästchen hinzu, um den Boden zu kennzeichnen, indem Sie a-box . Platzieren Sie diese direkt unter Ihrer Kamera aus der vorherigen Anleitung.

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

Ihre index.html -Datei sollte jetzt genau mit der folgenden übereinstimmen. Den vollständigen Quellcode finden Sie hier auf 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>

Damit ist die Einrichtung abgeschlossen. Als nächstes werden wir die Beleuchtung für eine mysteriösere Atmosphäre anpassen.

2. Atmosphäre hinzufügen

In diesem Schritt richten wir den Nebel und die benutzerdefinierte Beleuchtung ein.

Eine Vorschau auf eine einfache Szene mit düsterer Stimmung
Eine Vorschau einer einfachen Szene mit düsterer Stimmung (Große Vorschau)

Fügen Sie einen Nebel hinzu, der weit entfernte Objekte für uns verdunkelt. Ändern Sie das a-scene Tag in Zeile 8. Hier fügen wir einen dunklen Nebel hinzu, der schnell die Ränder des Bodens verdunkelt und den Effekt eines fernen Horizonts erzeugt.

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

Das Dunkelgrau #111 blendet linear von einer Entfernung von 10 bis zu einer Entfernung von 15 ein. Alle Objekte, die mehr als 15 Einheiten entfernt sind, werden vollständig verdeckt, und alle Objekte, die weniger als 10 Einheiten entfernt sind, sind vollständig sichtbar. Jedes Objekt dazwischen wird teilweise verdeckt.

Fügen Sie ein Umgebungslicht hinzu, um Objekte im Spiel aufzuhellen, und ein gerichtetes Licht, um reflektierende Oberflächen zu betonen, die Sie später hinzufügen werden. Platzieren Sie dies direkt nach dem a-scene Tag, das Sie in der vorherigen Anweisung geändert haben.

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

Fügen Sie direkt unter den Lichtern in der vorherigen Anweisung einen dunklen Himmel hinzu. Beachten Sie, dass das Dunkelgrau #111 dem des fernen Nebels entspricht.

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

Damit sind grundlegende Änderungen an der Stimmung und im weiteren Sinne am Szenenaufbau abgeschlossen. Überprüfen Sie, ob Ihr Code genau mit dem Quellcode für Schritt 2 auf Github übereinstimmt. Als Nächstes fügen wir eine Low-Poly-Kugel hinzu und beginnen mit der Anpassung der Ästhetik der Kugel.

Erstellen der Kugeln

3. Erstellen Sie eine Low-Poly-Kugel

In diesem Schritt erstellen wir eine rotierende, reflektierende Kugel, wie unten abgebildet. Die Kugel besteht aus zwei stilisierten Low-Poly-Kugeln mit ein paar Tricks, um reflektierendes Material vorzuschlagen.

Rotierende, reflektierende Kugel
(Große Vorschau)

Beginnen Sie mit dem Importieren der Low-Poly-Bibliothek in Ihr head -Tag. Fügen Sie Folgendes zwischen den Zeilen 4 und 5 ein.

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

Erstellen Sie ein Karussell, einen Wrapper und einen Orb-Container. Das carousel enthält mehrere Kugeln, die wrapper ermöglicht es uns, alle Kugeln um eine Mittelachse zu drehen, ohne jede Kugel einzeln zu drehen, und der container – wie der Name schon sagt – alle Kugelkomponenten.

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

Fügen Sie in den Kugelbehälter die Kugel selbst hinzu: Eine Kugel ist leicht durchscheinend und versetzt, und die andere ist vollständig fest. Die beiden kombinierten imitieren reflektierende Oberflächen.

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

Drehen Sie schließlich die Kugel auf unbestimmte Zeit, indem Sie das folgende a-animation Tag unmittelbar nach der lp-sphere innerhalb der .orb -Entität in der letzten Anweisung hinzufügen.

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

Ihr Quellcode für die Orb-Wrapper und die Kugel selbst sollten genau mit dem Folgenden übereinstimmen.

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

Überprüfen Sie, ob Ihr Quellcode mit dem vollständigen Quellcode für Schritt 3 auf Github übereinstimmt. Ihre Vorschau sollte jetzt wie folgt aussehen.

Rotierende, reflektierende Kugel
(Große Vorschau)

Als nächstes fügen wir der Kugel mehr Beleuchtung hinzu, um einen goldenen Farbton zu erhalten.

4. Beleuchten Sie die Kugel

In diesem Schritt fügen wir zwei Lichter hinzu, ein farbiges und ein weißes. Dies erzeugt den folgenden Effekt.

Orb beleuchtet mit Punktlichtern
(Große Vorschau)

Beginnen Sie damit, das weiße Licht hinzuzufügen, um das Objekt von unten zu beleuchten. Wir werden ein Punktlicht verwenden. Fügen Sie direkt vor #orb0 , aber innerhalb von #container-orb0 das folgende Offset-Punktlicht hinzu.

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

In Ihrer Vorschau sehen Sie Folgendes.

Orb beleuchtet mit weißem Punktlicht
(Große Vorschau)

Standardmäßig klingen Lichter nicht mit zunehmender Entfernung ab. Durch das Hinzufügen von distance="8" stellen wir sicher, dass das Licht bei einer Entfernung von 8 Einheiten vollständig zerfällt, um zu verhindern, dass das Punktlicht die gesamte Szene beleuchtet. Als nächstes fügen Sie das goldene Licht hinzu. Fügen Sie Folgendes direkt über dem letzten Licht hinzu.

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

Überprüfen Sie, ob Ihr Code genau mit dem Quellcode für Schritt 4 übereinstimmt. Ihre Vorschau wird nun wie folgt aussehen.

Orb beleuchtet mit Punktlichtern
(Große Vorschau)

Als Nächstes nehmen Sie Ihre endgültige ästhetische Änderung an der Kugel vor und fügen rotierende Ringe hinzu.

5. Fügen Sie Ringe hinzu

In diesem Schritt produzieren Sie die endgültige Kugel, wie unten abgebildet.

Goldene Kugel mit mehreren Ringen
(Große Vorschau)

Fügen Sie einen Ring in #container-orb0 direkt vor #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>

Beachten Sie, dass der Ring selbst keine Farbe enthält, da die Farbe im vorherigen Schritt vom Punktlicht durchdrungen wird. Außerdem ist das material="side:double" wichtig, da ohne es die Rückseite des Rings nicht gerendert würde; Dies bedeutet, dass der Ring für die Hälfte seiner Umdrehung verschwinden würde.

Die Vorschau mit nur dem obigen Code sieht jedoch nicht anders aus. Dies liegt daran, dass der Ring derzeit senkrecht zum Bildschirm steht. Somit ist nur die „Seite“ des Rings (die eine Dicke von 0 hat) sichtbar. Platzieren Sie die folgende Animation zwischen den a-ring Tags in der vorherigen Anweisung.

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

Ihre Vorschau sollte nun wie folgt aussehen:

Goldene Kugel mit Ring
(Große Vorschau)

Erstellen Sie eine variable Anzahl von Ringen mit unterschiedlichen Rotationsachsen, Geschwindigkeiten und Größen. Sie können die folgenden Beispielringe verwenden. Alle neuen Ringe sollten unter dem letzten a-ring platziert werden.

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

Ihre Vorschau wird nun wie folgt aussehen.

Goldene Kugel mit mehreren Ringen
(Große Vorschau)

Überprüfen Sie, ob Ihr Code mit dem Quellcode für Schritt 5 auf Github übereinstimmt. Dies schließt das Dekor für die Kugel ab. Wenn die Kugel fertig ist, werden wir der Kugel als nächstes Interaktivität hinzufügen. Im nächsten Schritt fügen wir speziell einen sichtbaren Cursor mit einer Klickanimation hinzu, wenn er auf anklickbare Objekte zeigt.

The Orbs interaktiv machen

6. Fügen Sie einen Cursor hinzu

In diesem Schritt fügen wir einen weißen Cursor hinzu, der anklickbare Objekte auslösen kann. Der Cursor ist unten abgebildet.

Klick auf Kugel
(Große Vorschau)

Fügen Sie in Ihrem a-camera Tag die folgende Entität hinzu. Das fuse ermöglicht dieser Entität die Fähigkeit, Klickereignisse auszulösen. Das raycaster Attribut bestimmt, wie oft und wie weit nach anklickbaren Objekten gesucht wird. Das objects akzeptiert einen Selektor, um zu bestimmen, welche Entitäten anklickbar sind. In diesem Fall sind alle Objekte der Klasse clickable anklickbar.

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

Fügen Sie als Nächstes eine Cursoranimation und einen zusätzlichen Ring für die Ästhetik hinzu. Platzieren Sie Folgendes innerhalb des Entity-Cursor-Objekts oben. Dadurch wird dem Cursorobjekt eine Animation hinzugefügt, sodass Klicks sichtbar sind.

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

Fügen Sie als Nächstes die clickable Klasse zu #orb0 , um Folgendes abzugleichen.

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

Überprüfen Sie, ob Ihr Code mit dem Quellcode für Schritt 6 auf Github übereinstimmt. Ziehen Sie in Ihrer Vorschau den Mauszeiger von ihnen weg auf die Kugel, um die Klickanimation in Aktion zu sehen. Dies ist unten abgebildet.

Klick auf Kugel
(Große Vorschau)

Beachten Sie, dass das anklickbare Attribut der Kugel selbst und nicht dem Kugelcontainer hinzugefügt wurde. Dadurch soll verhindert werden, dass die Ringe zu anklickbaren Objekten werden. Auf diese Weise muss der Benutzer auf die Kugeln klicken, aus denen die Kugel selbst besteht.

In unserem letzten Schritt für diesen Teil fügen Sie eine Animation hinzu, um die Ein- und Aus-Zustände für die Kugel zu steuern.

7. Fügen Sie Kugelzustände hinzu

In diesem Schritt animieren Sie die Kugel beim Klicken in den Aus-Zustand und aus dem Aus-Zustand. Dies ist unten abgebildet.

Interaktive Kugel, die auf Klicks reagiert
(Große Vorschau)

Zu Beginn werden Sie die Kugel schrumpfen und auf den Boden senken. Fügen Sie direkt nach #orb0 a-animation Tags zu #container-orb0 hinzu. Beide Animationen werden durch einen Klick ausgelöst und haben dieselbe Easing-Funktion: ease-elastic für ein leichtes Springen.

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

Um den Aus-Zustand weiter hervorzuheben, entfernen wir das goldene Punktlicht, wenn die Kugel ausgeschaltet ist. Die Lichter der Kugel werden jedoch außerhalb des Kugelobjekts platziert. Somit wird das Click-Ereignis nicht an die Lichter weitergegeben, wenn auf die Kugel geklickt wird. Um dieses Problem zu umgehen, verwenden wir ein leichtes Javascript, um das Klickereignis an das Licht weiterzuleiten. Platzieren Sie das folgende Animations-Tag in #light-orb0 . Das Licht wird durch ein benutzerdefiniertes switch ausgelöst.

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

Fügen Sie als Nächstes den folgenden Click-Ereignis-Listener zu #container-orb0 . Dadurch werden die Klicks an die Kugellichter weitergeleitet.

 <a-entity ...>

Überprüfen Sie, ob Ihr Code mit dem Quellcode für Schritt 7 auf Github übereinstimmt. Rufen Sie schließlich Ihre Vorschau auf und bewegen Sie den Cursor auf und von der Kugel, um zwischen Aus- und Ein-Zuständen umzuschalten. Dies ist unten abgebildet.

Interaktive Kugel, die auf Klicks reagiert
(Große Vorschau)

Damit ist die Interaktivität der Kugel abgeschlossen. Der Spieler kann jetzt Kugeln nach Belieben ein- und ausschalten, mit selbsterklärenden Ein- und Aus-Zuständen.

Fazit

In diesem Tutorial haben Sie eine einfache Kugel mit Ein- und Aus-Zuständen erstellt, die durch einen VR-Headset-freundlichen Cursorklick umgeschaltet werden kann. Mit einer Reihe verschiedener Beleuchtungstechniken und Animationen konnten Sie zwischen den beiden Zuständen unterscheiden. Damit sind die Virtual-Reality-Designelemente für die Kugeln abgeschlossen. Im nächsten Teil des Tutorials werden wir die Kugeln dynamisch bevölkern, Spielmechaniken hinzufügen und ein Kommunikationsprotokoll zwischen zwei Spielern einrichten.