Devlog: Multiplayer voor Mixed Reality

Devlog: Multiplayer voor Mixed Reality

Thijs ReusThijs Reus
·19 september 2025·11 min. leestijd
Let op: dit bericht is automatisch vertaald.

We vervolgen onze verkenning van Mixed Reality-capaciteiten van de Meta Quest 3 met Unreal Engine en de MetaXR-plugin die we zijn begonnen in een vorige devlog-post.

In dit bericht kijken we naar het toevoegen van multiplayer-capaciteiten met behulp van de uitstekende VR-Expansion Plugin voor Unreal Engine.

Tech Stack

Voor deze verkenning gebruiken we de volgende tech stack:

Multiplayer - cool maar complex

Multiplayer-ondersteuning stelt meerdere gebruikers in staat om dezelfde virtuele ervaring te delen, interagerend met de virtuele wereld op een coöperatieve of competitieve manier. Dergelijke ervaringen kunnen puur virtueel zijn, waardoor spelers niet per se in dezelfde fysieke ruimte hoeven te zijn, of mixed reality waarbij spelers typisch gecolocateerd zijn in dezelfde fysieke ruimte. Dit maakt echt coole ervaringen mogelijk met meerdere mensen, maar helaas is er geen gratis lunch.

Het ondersteunen van multiplayer voegt veel technische complexiteit toe aan een project (wat ver buiten het bereik van dit blogartikel gaat), gezien dat een client/server-opstelling vereist is, wat onvermijdelijk latentie toevoegt aan de ervaring vanwege de continue replicatie van gegevens tussen de clients (voornamelijk verantwoordelijk voor gebruikersinvoer, het renderen van de scène en het afspelen van audio/animaties) en de server (het heeft autoriteit over alles wat gebeurt in de map, zoals fysica, interacties en game-logica, en repliceert relevante gegevens naar alle relevante clients). Opmerkelijk is dat Unreal Engine clients alleen kunnen communiceren met de server, en de server kan communiceren met elke client, dus er is geen directe communicatie tussen clients.

Vooral wanneer je een VR-headset draagt, is elke vorm van latentie door replicatie onmiddellijk merkbaar (bijv. wanneer de virtuele camera/handen achterblijven bij de fysieke headset/controller positie/oriëntatie), wat kan leiden tot bewegingsziekte - dus dit moet ten koste van alles worden vermeden.

Veel van deze complexiteit is gelukkig al opgelost door de VR-Expansion Plugin voor Unreal Engine, vooral op het gebied van het repliceren van VR-elementen tussen clients en de server om een soepele VR-ervaring te garanderen. Het heeft een geweldig voorbeeldproject dat kan worden gebruikt als inspiratie en begeleiding voor hoe de plugin correct wordt gebruikt.

Wijzigingen voor Multiplayer-ondersteuning

Vergeleken met een standaard VRTemplate-project in Unreal Engine, moeten ten minste de volgende opmerkelijke wijzigingen worden gemaakt bij het gebruik van de VR-Expansion Plugin:

  • Gebruik een VRPlayerController in plaats van een standaard PlayerController
  • Gebruik een VRCharacter in plaats van een standaard Pawn of Character
  • Gebruik een GrippableActor (bijv. GrippableStaticMeshActor) in plaats van het toevoegen van GrabComponent aan een Actor

Een setup zoals deze werkt heel goed voor virtual reality-ervaringen. Voor mixed reality-ervaringen (ten minste met de MetaXR plugin) moeten we echter enkele aanpassingen maken om het goed te laten werken.

Mixed Reality vereist verdere aanpassingen

Zodra we een mixed reality-ervaring hebben met de MetaXR plugin die een Scene gebruikt (waarbij de headset de kamer scant om elementen zoals muren/vloer/plafond/meubels te identificeren), merken we een onmiddellijk probleem op bij het gebruik van de setup uit de vorige sectie: de camera is vastgelockt op de vloer, in plaats van de verwachte positie, ongeacht of de headset omhoog of omlaag wordt bewogen in de realiteit.

Camera is vastgelockt op de vloer, wat niet ideaal is
Camera is vastgelockt op de vloer, wat niet ideaal is
Alle virtuele elementen bevinden zich op de verkeerde locatie
Alle virtuele elementen bevinden zich op de verkeerde locatie

Dit gebeurt omdat de MetaXR plugin standaard een functie World Lock heeft in MRUtilityKit, die de floor anchor gebruikt om de virtuele wereld visueel op zijn plaats te vergrendelen, zelfs voor actors die niet verankerd zijn. Het verankeren van een actor aan een Scene zorgt ervoor dat zijn locatie/oriëntatie altijd consistent is met de fysieke ruimte, ongeacht hoe de initiële headsetpositie/oriëntatie was, wat vrij essentieel is om consistente mixed reality-ervaringen te maken.

De World Lock-functie vergelijkt in wezen de verankerde locatie/oriëntatie van de floor anchor met de virtuele floor actor locatie/oriëntatie, en offset de PlayerCharacter met dit bedrag om de camera te verplaatsen - effectief 'bewegend' de hele virtuele wereld om het goed uitgelijnd te houden met de fysieke wereld. Dit gebeurt elke tick, om een soepele ervaring te garanderen.

Dus waarom is de camera vastgelockt op de vloer bij het gebruik van de VRCharacter, terwijl het zonder problemen werkt met een standaard Pawn/Character? Blijkbaar is een van de componenten van de VRCharacter, namelijk NetSmoother, geoffset met -98.15 op de Z-as, wat het effect heeft dat normaal gesproken de VRCharacter zich bevindt op een Z-coördinaat van ongeveer 98.15, ervan uitgaande dat de vloer zich bevindt op Z-coördinaat 0. Echter, met de World Lock-functie die de VRCharacter locatie/oriëntatie instelt op het verschil tussen de verankerde en virtuele floor actor locatie/oriëntatie, is dit meestal rond 0, wat in principe de hele VRCharacter (inclusief camera en handen) bijna 1 virtuele meter naar beneden beweegt.

Om dit symptoom op te lossen, hebben we de volgende wijziging gemaakt aan onze VRCharacter subklasse:

  • Stel de positie van de NetSmoother-component in op (0, 0, 0) in plaats van (0, 0, -98.15)

We hebben nog geen negatieve neveneffecten van deze aanpassing waargenomen, en de World Lock-functie werkt goed met die wijziging.

Net Smoother component locatie aangepast
Net Smoother component locatie aangepast
Camera en alle virtuele elementen bevinden zich op de juiste locatie
Camera en alle virtuele elementen bevinden zich op de juiste locatie

Daarnaast passen we de volgende wijzigingen toe in onze VRCharacter subklasse om ervoor te zorgen dat de VRCharacter niet beweegt, omdat dit immersie zou breken:

  • EnableGravity is uitgeschakeld
  • GravityScale is ingesteld op 0
  • HMDTrackingOrigin is ingesteld op Stage in plaats van Floor
  • RetainRoomscale is ingesteld op true
  • Locomotie is uitgeschakeld

MetaXR plugin functies moeten alleen worden gebruikt op headsets

Om multiplayer-functies in te schakelen, is een server vereist, idealiter een dedicated server die niet op de headset draait, om ervoor te zorgen dat de headset zoveel mogelijk prestaties/batterij beschikbaar heeft voor de client-side van de ervaring.

Een dedicated server draait typisch op Windows of Linux, en het gebruik van de MetaXR plugin voor mixed reality voegt een beetje uitdaging toe aan dergelijke setups, gezien dat de MetaXR plugin-functionaliteit alleen werkt op een headset, en Linux niet ondersteunt als platform out of the box.

Voorwaardelijke kamer-setup

Bij het bouwen van een dedicated server (wat al een beetje een uitdaging op zich is) voor Windows of Linux, moeten we ervoor zorgen dat de MetaXR-functionaliteit niet wordt gebruikt.

Ons uitgangspunt voor die functionaliteit is in de blueprint BP_RoomSetup, die normaal gesproken de kamer-setup zou starten zodra deze wordt gemaakt (in de BeginPlay-event). Om ervoor te zorgen dat deze functionaliteit alleen wordt uitgevoerd op een headset (of wanneer een headset aanwezig is, bijv. via AirLink), voegen we de volgende voorwaarden toe aan de kamer-setup:

  • De PlayerController is lokaal gecontroleerd, wat betekent dat we op een client draaien
  • De HMD is verbonden, wat betekent dat er ten minste een HMD aanwezig is
  • De applicatie is niet gestart met de -unattended optie
  • De applicatie draait in VRPreview of een gepackagede build
Voorwaardelijke Kamer Setup
Voorwaardelijke Kamer Setup

Op deze manier wordt de werkelijke kamer-setup alleen gedaan op een APK die draait op de headset, of een Play-In-Editor-instantie bijv. via AirLink. Op een dedicated server, of een non-VR-client wordt de kamer-setup genegeerd.

De onderstaande afbeeldingen tonen wat een client op de headset en een (non-VR) Windows-client zien (de andere speler wordt vertegenwoordigd met 2 handen, een kubus voor een hoofd en een platte cilinder voor een lichaam).

Een client op de headset ziet kamerelementen
Een client op de headset ziet kamerelementen
Een non-VR Windows-client ziet geen kamerelementen
Een non-VR Windows-client ziet geen kamerelementen

Het repliceren van kamerelementen van een headset-client naar de server en andere clients is nog werk in uitvoering.

Dedicated server voor Linux met MetaXR plugin

Standaard ondersteunt de MetaXR plugin het Linux-platform niet, in plaats daarvan ondersteunt het alleen Win64 en Android doelplatforms. Bij het proberen een dedicated server te bouwen voor Linux voor een project dat de MetaXR plugin bevat, resulteert dit normaal gesproken in een fout dat het platform niet wordt ondersteund.

Als workaround kan het OculusXR.uplugin worden aangepast om Linux toe te voegen in de SupportedTargetPlatforms array:

...
"SupportedTargetPlatforms": [
	"Win64",
	"Android",
	"Linux"
],
...

De build zal dan slagen, zonder tot nu toe merkbare problemen.

Conclusie

Mixed Reality is een opwindende manier om unieke ervaringen te creëren die de echte en virtuele wereld mengen. Dergelijke ervaringen kunnen verder worden verbeterd door meerdere gebruikers deel te laten nemen met multiplayer-functies, zodat ze kunnen samenwerken of concurreren voor een bepaald doel.

Wij bij Immerstory zijn enthousiast om onze klanten te ondersteunen met hun immersieve ervaringen, en kijken ernaar uit om binnenkort meer verkenning voortgang te delen.

Welke immersieve ervaring zou je graag willen zien? Laat het ons weten!

Aanvullende bronnen

Documentatie voor de MetaXR plugin, specifiek de Mixed Reality Utility Kit die voor deze demo werd gebruikt, is te vinden hier

Meer van de blog