Lokale ankeroverdrachten in Unity
Met lokale ankeroverdrachten kan één HoloLens-apparaat een anker exporteren dat moet worden geïmporteerd door een tweede HoloLens-apparaat.
Notitie
iOS- en Android-apparaten worden niet ondersteund door deze methode.
De mogelijkheid SpatialPerception instellen
Als u wilt dat een app ruimtelijke ankers overbrengt, moet de mogelijkheid SpatialPerception zijn ingeschakeld.
De mogelijkheid SpatialPerception inschakelen:
- Open in de Unity Editor het deelvenster Spelerinstellingen (Project Settings > Player bewerken>)
- Klik op het tabblad Windows Store
- Vouw Publicatie-instellingen uit en controleer de mogelijkheid SpatialPerception in de lijst Mogelijkheden
Notitie
Als u uw Unity-project al hebt geëxporteerd naar een Visual Studio-oplossing, moet u exporteren naar een nieuwe map of deze mogelijkheid handmatig instellen in appxManifest in Visual Studio.
Ankeroverdracht
Naamruimte: UnityEngine.XR.WSA.Sharing
Type: WorldAnchorTransferBatch
Om een WorldAnchor over te dragen, moet men het anker instellen dat moet worden overgedragen. De gebruiker van een HoloLens scant hun omgeving en kiest handmatig of programmatisch een punt in de ruimte om het anker voor de gedeelde ervaring te zijn. De gegevens die dit punt vertegenwoordigen, kunnen vervolgens worden geserialiseerd en verzonden naar de andere apparaten die in de ervaring worden gedeeld. Elk apparaat maakt vervolgens de serialisatie van de ankergegevens ongedaan en probeert dat punt in de ruimte te vinden. Om ankeroverdracht te laten werken, moet elk apparaat in voldoende omgeving zijn gescand, zodat het punt dat door het anker wordt vertegenwoordigd, kan worden geïdentificeerd.
Instellingen
De voorbeeldcode op deze pagina bevat enkele velden die moeten worden geïnitialiseerd:
- GameObject rootGameObject is een GameObject in Unity met een WorldAnchor Component erop. Eén gebruiker in de gedeelde ervaring plaatst dit GameObject en exporteert de gegevens naar de andere gebruikers.
- WorldAnchor gameRootAnchor is de UnityEngine.XR.WSA.WorldAnchor die zich op rootGameObject bevindt.
- byte[] importedData is een bytematrix voor het geserialiseerde anker dat elke client via het netwerk ontvangt.
public GameObject rootGameObject;
private UnityEngine.XR.WSA.WorldAnchor gameRootAnchor;
void Start ()
{
gameRootAnchor = rootGameObject.GetComponent<UnityEngine.XR.WSA.WorldAnchor>();
if (gameRootAnchor == null)
{
gameRootAnchor = rootGameObject.AddComponent<UnityEngine.XR.WSA.WorldAnchor>();
}
}
Exporteren
Om te exporteren, hebben we alleen een WorldAnchor nodig en om te weten wat we het zo noemen dat het zinvol is voor de ontvangende app. Eén client in de gedeelde ervaring voert deze stappen uit om het gedeelde anker te exporteren:
- Een WorldAnchorTransferBatch maken
- De WorldAnchors toevoegen om over te dragen
- De export starten
- De gebeurtenis OnExportDataAvailable verwerken wanneer gegevens beschikbaar komen
- De gebeurtenis OnExportComplete afhandelen
We maken een WorldAnchorTransferBatch om in te kapselen wat we gaan overbrengen en vervolgens exporteren naar bytes:
private void ExportGameRootAnchor()
{
WorldAnchorTransferBatch transferBatch = new WorldAnchorTransferBatch();
transferBatch.AddWorldAnchor("gameRoot", this.gameRootAnchor);
WorldAnchorTransferBatch.ExportAsync(transferBatch, OnExportDataAvailable, OnExportComplete);
}
Wanneer er gegevens beschikbaar komen, verzendt u de bytes naar de client of buffer als er gegevenssegmenten beschikbaar zijn en verzendt u de gewenste middelen:
private void OnExportDataAvailable(byte[] data)
{
TransferDataToClient(data);
}
Zodra de export is voltooid, moet de client de gegevens negeren als we gegevens en serialisatie hebben overgedragen. Als de serialisatie is geslaagd, laat u de client weten dat alle gegevens zijn overgedragen en importeren kan worden gestart:
private void OnExportComplete(SerializationCompletionReason completionReason)
{
if (completionReason != SerializationCompletionReason.Succeeded)
{
SendExportFailedToClient();
}
else
{
SendExportSucceededToClient();
}
}
Importeren
Nadat alle bytes van de afzender zijn ontvangen, kunnen we de gegevens weer importeren in een WorldAnchorTransferBatch en ons hoofdspelobject op dezelfde fysieke locatie vergrendelen. Opmerking: importeren mislukt soms tijdelijk en moet opnieuw worden geprobeerd:
// This byte array should have been updated over the network from TransferDataToClient
private byte[] importedData;
private int retryCount = 3;
private void ImportRootGameObject()
{
WorldAnchorTransferBatch.ImportAsync(importedData, OnImportComplete);
}
private void OnImportComplete(SerializationCompletionReason completionReason, WorldAnchorTransferBatch deserializedTransferBatch)
{
if (completionReason != SerializationCompletionReason.Succeeded)
{
Debug.Log("Failed to import: " + completionReason.ToString());
if (retryCount > 0)
{
retryCount--;
WorldAnchorTransferBatch.ImportAsync(importedData, OnImportComplete);
}
return;
}
this.gameRootAnchor = deserializedTransferBatch.LockObject("gameRoot", this.rootGameObject);
}
Nadat een GameObject is vergrendeld via de call LockObject , heeft het een WorldAnchor die het in dezelfde fysieke positie ter wereld houdt, maar het kan zich op een andere locatie in de Unity-coördinaatruimte bevinden dan andere gebruikers.