Sistemi di coordinate in Unity

Windows Realtà mista supporta le app in un'ampia gamma di scalabilità di esperienze, da app di sola orientamento e con scalabilità verticale tramite app su scala locale. In HoloLens è possibile proseguire e creare app su scala mondiale che consentono agli utenti di superare i 5 metri, esplorando un intero piano di un edificio e oltre.

Il primo passaggio per creare 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 orientamento o di sola seduta

Spazio dei nomi: UnityEngine.XR
Tipo: XRDevice

Per creare un'esperienza di orientamento o di sola posizione, è necessario impostare Unity sul tipo di spazio di rilevamento stazioni. Lo spazio di rilevamento stazioni imposta il sistema di coordinate del mondo di Unity per tenere traccia della cornice di riferimento stazionaria. Nella modalità di rilevamento stazioni, il contenuto posizionato 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
Tipo: InputTracking

Per un'esperienza pura di sola orientamento, 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 in un secondo momento di aggiornare l'origine seduta, è possibile chiamare la XR. Metodo InputTracking.Recenter:

InputTracking.Recenter();

Creazione di un'esperienza su scala in piedi o su scala locale

Spazio dei nomi: UnityEngine.XR
Tipo: 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 sala, 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 stanza 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 la configurazione della stanza, con -Z che rappresenta la direzione in avanti che si trovavano durante l'installazione.

Spazio dei nomi: UnityEngine.Experimental.XR
Tipo: Limite

Nel codice 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 (si ottiene un elenco di vertici), è sicuro offrire un'esperienza su scala locale all'utente, in cui può spostarsi intorno alla 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 scena usando questo poligono limite, per garantire che l'utente possa raggiungere fisicamente tali oggetti senza teletrasportarsi:

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
Tipo: WorldAnchor

Per le vere esperienze su scala mondiale in HoloLens che consentono agli utenti di andare oltre 5 metri, sono necessarie nuove tecniche oltre quelle usate per le esperienze su scala locale. Una tecnica chiave che verrà usata consiste nel creare un ancoraggio nello spazio 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 gli 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 globale, chiama AddComponent<WorldAnchor>() sull'oggetto gioco con la trasformazione che vuoi ancorare nel mondo reale.

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

Ecco fatto! 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 di app futura.

Rimozione di un ancoraggio globale

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

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

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

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

Spostamento di un GameObject ancorato al mondo

Non è possibile spostare l'oggetto GameObject mentre è attivo un ancoraggio del mondo. Se è necessario spostare il GameObject in questo frame, è necessario:

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

Gestione delle modifiche di individuazione

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 della individuabilità, l'oggetto non viene 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 nello spazio sottostante cambia tra uno stato di essere locatable e non essere locabile.

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 di Ancoraggi nello spazio di Azure di 5 minuti.

Dopo aver eseguito 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 sta esplorando i blocchi predefiniti di base di Realtà mista. Da qui, è possibile passare al blocco predefinito successivo:

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

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

Vedi anche