Sistemi di coordinate in Unity

Windows Mixed Reality supporta le app in un'ampia gamma di scalabilità di esperienze, da app di sola orientamento e con scalabilità verticale tramite app su larga scala. In HoloLens è possibile approfondire e creare app su scala mondiale che consentono agli utenti di camminare oltre 5 metri, esplorando un intero piano di un edificio e oltre.

Il primo passaggio per la creazione di un'esperienza di realtà mista in Unity consiste nel comprendere i sistemi di coordinate e scegliere la scalabilità dell'esperienza di destinazione dell'app.

Creazione di un'esperienza di sola orientamento o su scala seduta

Spazio dei nomi:UnityEngine.XR
Type:XRDevice

Per creare un'esperienza di sola orientamento o con scala seduta, è necessario impostare Unity sul tipo di spazio di rilevamento stazioni. Lo spazio di rilevamento stazioni imposta il sistema di coordinate mondiali di Unity per tenere traccia del frame di riferimento fisso. Nella modalità di rilevamento stazioni, il contenuto inserito nell'editor appena davanti alla posizione predefinita della fotocamera (forward è -Z) verrà visualizzato davanti all'utente all'avvio dell'app.

XRDevice.SetTrackingSpaceType(TrackingSpaceType.Stationary);

Spazio dei nomi:UnityEngine.XR
Type:InputTracking

Per un'esperienza di sola orientamento pura, ad esempio un visualizzatore video a 360 gradi (in cui gli aggiornamenti della testa posizionale rovinano l'illusione), è quindi possibile impostare XR. InputTracking.disablePositionalTracking su true:

InputTracking.disablePositionalTracking = true;

Per un'esperienza di ridimensionamento seduto, per consentire all'utente di aggiornare in un secondo momento l'origine seduta, è possibile chiamare la XR. Metodo InputTracking.Recenter :

InputTracking.Recenter();

Creazione di un'esperienza su scala permanente o su scala locale

Spazio dei nomi:UnityEngine.XR
Type:XRDevice

Per un'esperienza su scala in piedi o su scala locale, è necessario posizionare il contenuto rispetto al pavimento. Si tratta del piano dell'utente usando la fase spaziale, che rappresenta l'origine a livello di piano definita dall'utente e il limite facoltativo della stanza, configurato durante la prima esecuzione.

Per assicurarsi che Unity funzioni con il sistema di coordinate globale a livello di piano, è possibile impostare e testare che Unity usi il tipo di spazio di rilevamento RoomScale:

if (XRDevice.SetTrackingSpaceType(TrackingSpaceType.RoomScale))
{
    // RoomScale mode was set successfully.  App can now assume that y=0 in Unity world coordinate represents the floor.
}
else
{
    // RoomScale mode was not set successfully.  App cannot make assumptions about where the floor plane is.
}
  • Se SetTrackingSpaceType restituisce true, Unity ha cambiato correttamente il sistema di coordinate del mondo per tenere traccia del frame di fase di riferimento.
  • Se SetTrackingSpaceType restituisce false, Unity non è riuscito a passare al frame di fase di riferimento, probabilmente perché l'utente non ha configurato un piano nel proprio ambiente. Anche se un valore restituito falso non è comune, può verificarsi se la fase è configurata in una stanza diversa e il dispositivo viene spostato nella sala corrente senza che l'utente configuri una nuova fase.

Dopo che l'app imposta correttamente il tipo di spazio di rilevamento RoomScale, il contenuto posizionato sul piano y=0 verrà visualizzato sul pavimento. L'origine a 0, 0, 0 sarà il luogo specifico sul pavimento in cui l'utente si trovava durante l'installazione della stanza, con -Z che rappresenta la direzione in avanti rivolta durante l'installazione.

Spazio dei nomi:UnityEngine.Experimental.XR
Type:Boundary

Nel codice di script è quindi possibile chiamare il metodo TryGetGeometry nel tipo UnityEngine.Experimental.XR.Boundary per ottenere un poligono limite, specificando un tipo di limite di TrackedArea. Se l'utente ha definito un limite (viene restituito un elenco di vertici), è sicuro offrire un'esperienza su scala locale all'utente, in cui è possibile spostarsi nella scena creata.

Nota

Il sistema eseguirà automaticamente il rendering del limite quando l'utente lo avvicina. L'app non deve usare questo poligono per eseguire il rendering del limite stesso. Tuttavia, è possibile scegliere di disporre gli oggetti della scena usando questo poligono limite, per assicurarsi che l'utente possa raggiungere fisicamente tali oggetti senza teletrasportare:

var vertices = new List<Vector3>();
if (UnityEngine.Experimental.XR.Boundary.TryGetGeometry(vertices, Boundary.Type.TrackedArea))
{
    // Lay out your app's content within the boundary polygon, to ensure that users can reach it without teleporting.
}

Creazione di un'esperienza su scala mondiale

Spazio dei nomi:UnityEngine.XR.WSA
Type:WorldAnchor

Per le vere esperienze su scala mondiale in HoloLens che consentono agli utenti di andare oltre 5 metri, sono necessarie nuove tecniche oltre a quelle usate per le esperienze su scala locale. Una tecnica chiave che verrà usata consiste nel creare un ancoraggio spaziale per bloccare un cluster di ologrammi esattamente sul posto nel mondo fisico, indipendentemente dalla distanza in cui l'utente ha eseguito il roaming e quindi trovare nuovamente tali ologrammi nelle sessioni successive.

In Unity si crea un ancoraggio nello spazio aggiungendo il componente WorldAnchor Unity a un GameObject.

Aggiunta di un ancoraggio globale

Per aggiungere un ancoraggio del mondo, chiama AddComponent<WorldAnchor>() sull'oggetto gioco con la trasformazione che vuoi ancorare nel mondo reale.

WorldAnchor anchor = gameObject.AddComponent<WorldAnchor>();

L'operazione è terminata. Questo oggetto gioco verrà ora ancorato alla posizione corrente nel mondo fisico. È possibile che le coordinate del mondo Unity si adattino leggermente nel tempo per garantire l'allineamento fisico. Usa la persistenza per trovare di nuovo questa posizione ancorata in una sessione futura dell'app.

Rimozione di un ancoraggio globale

Se non vuoi più che il GameObject sia bloccato in una posizione fisica e non intendi spostarlo in questo fotogramma, puoi semplicemente chiamare Destroy sul componente World Anchor.

Destroy(gameObject.GetComponent<WorldAnchor>());

Se vuoi spostare il GameObject in questo frame, devi invece chiamare DestroyImmediate.

DestroyImmediate(gameObject.GetComponent<WorldAnchor>());

Spostamento di un GameObject ancorato al mondo

Non è possibile spostare gameobject mentre è attivo un ancoraggio globale. Se è necessario spostare il GameObject in questo frame, è necessario:

  1. DestroyImmediate il componente World Anchor
  2. Spostare il GameObject
  3. Aggiungere un nuovo componente Di ancoraggio globale al GameObject.
DestroyImmediate(gameObject.GetComponent<WorldAnchor>());
gameObject.transform.position = new Vector3(0, 0, 2);
WorldAnchor anchor = gameObject.AddComponent<WorldAnchor>();

Gestione delle modifiche di individuabilità

Un WorldAnchor potrebbe non essere individuabile nel mondo fisico in un momento specifico. In tal caso, Unity non aggiornerà la trasformazione dell'oggetto ancorato. Questo può anche cambiare durante l'esecuzione di un'app. Se non si gestisce la modifica nella individuabilità, l'oggetto non verrà visualizzato nella posizione fisica corretta nel mondo.

Per ricevere una notifica sulle modifiche alla individuabilità:

  1. Sottoscrivere l'evento OnTrackingChanged
  2. Gestire l'evento

L'evento OnTrackingChanged verrà chiamato ogni volta che l'ancoraggio spaziale sottostante cambia tra uno stato di essere locatable e non è locatable.

anchor.OnTrackingChanged += Anchor_OnTrackingChanged;

Gestire quindi l'evento:

private void Anchor_OnTrackingChanged(WorldAnchor self, bool located)
{
    // This simply activates/deactivates this object and all children when tracking changes
    self.gameObject.SetActiveRecursively(located);
}

A volte gli ancoraggi si trovano immediatamente. In questo caso, questa proprietà isLocated dell'ancoraggio verrà impostata su true quando viene restituito AddComponent<WorldAnchor>(). Di conseguenza, l'evento OnTrackingChanged non verrà attivato. Un modello pulito consiste nel chiamare il gestore OnTrackingChanged con lo stato IsLocated iniziale dopo aver collegato un ancoraggio.

Anchor_OnTrackingChanged(anchor, anchor.isLocated);

Condivisione di ancoraggi tra dispositivi

Usare Ancoraggi nello spazio di Azure per creare un ancoraggio cloud durevole da un WorldAnchor locale, che l'app può quindi individuare in più dispositivi HoloLens, iOS e Android. Condividendo un ancoraggio spaziale comune tra più dispositivi, ogni utente può visualizzare il contenuto di cui è stato eseguito il rendering rispetto a tale ancoraggio nella stessa posizione fisica. Ciò rende possibili esperienze condivise in tempo reale.

Per iniziare a creare esperienze condivise in Unity, provare le guide introduttive di Unity per ancoraggi nello spazio di Azure di 5 minuti.

Una volta eseguiti con Ancoraggi nello spazio di Azure, è possibile creare e individuare ancoraggi in Unity.

Successivo checkpoint di sviluppo

Se si sta seguendo il percorso del checkpoint di sviluppo di Unity, si è in corso l'esplorazione dei blocchi predefiniti di base Realtà mista. Da qui è possibile passare al blocco predefinito successivo:

In alternativa, passare alle API e funzionalità della piattaforma di realtà mista:

È sempre possibile tornare ai checkpoint per lo sviluppo con Unity in qualsiasi momento.

Vedere anche