Trucchi per la persistenza

La persistenza è disponibile se supportata dalla piattaforma sottostante. Attualmente, questo è limitato alla famiglia di dispositivi HoloLens, usando il supporto VR predefinito di Unity (Legacy XR).

Persistenza di base

La persistenza di base per gli strumenti di blocco globale è abilitata per impostazione predefinita. Questa abilitazione è disponibile in due parti.

Impostazioni di controllo per la persistenza

Le caselle di controllo pertinenti sono le caselle di controllo "Caricamento automatico" e "Salvataggio automatico", che vengono controllate. Potresti notare che sono disattivati. Ciò è dovuto al fatto che fanno parte della scelta "Usa impostazioni predefinite". La disabilitazione di "Usa impostazioni predefinite" consente di selezionare combinazioni arbitrarie delle opzioni di automazione.

Altre informazioni sono disponibili su queste impostazioni e su come modificarle dallo script.

AutoSave

L'opzione Salvataggio automatico indirizza WLT a salvare lo stato frequente e regolare durante l'esecuzione dell'applicazione. In qualsiasi momento, l'applicazione può essere terminata con una perdita minima di stato.

AutoLoad

L'opzione AutoLoad indirizza WLT al caricamento di qualsiasi stato salvato in precedenza all'avvio. In questo modo l'applicazione può riprendere una nuova sessione in cui è stata interrotta (w.r.t. WLT) dall'ultima sessione.

Persistenza completa

Con il salvataggio automatico e il caricamento automatico abilitato, WLT funziona perfettamente tra le sessioni. Mentre la posizione e l'orientamento dello spazio globale sono arbitrari nella prima esecuzione (poiché non è stato salvato alcuno stato precedente, usa la posizione head all'avvio come origine), le esecuzioni successive condivideranno lo stesso frame di coordinate.

Questo comporta un comportamento interessante quando l'applicazione avvia una nuova sessione in uno spazio disconnesso dallo spazio della sessione precedente. Per informazioni dettagliate, vedere la sezione relativa alla persistenza per località più avanti.

Nota

Le impostazioni di salvataggio automatico e caricamento automatico si applicano anche a SpacePins globali. Vedere più avanti per informazioni dettagliate.

Controllo dell'applicazione sulla persistenza

La persistenza completa predefinita è adatta a un'ampia gamma di applicazioni.

Alcune applicazioni, tuttavia, potrebbero voler controllare in modo più corretto il processo.

Può sembrare strano che l'abilitazione della persistenza automatica WLT sia suddivisa in due proprietà, il salvataggio automatico e il caricamento automatico. L'esame dei casi in cui i due vengono usati in modo indipendente potrebbe fornire informazioni dettagliate sul sistema di persistenza complessivo.

Salvataggio automatico ma non caricamento automatico

Impostazione per il salvataggio automatico ma il caricamento controllato dall'applicazione

Con questa configurazione, WLT è impostato per salvare periodicamente lo stato. Tuttavia, non caricherà automaticamente alcuno stato persistente all'avvio.

Invece, il sistema verrà avviato in uno stato nuovo, come se fosse la prima volta che viene eseguito su questo dispositivo. Solo dopo una richiesta esplicita a Load() ripristina lo stato della sessione precedente.

In questo modo l'applicazione può decidere se ripristinare o meno lo stato precedente della sessione sarebbe appropriato e anche modificare i dati da ripristinare, se necessario.

Lo stato di salvataggio WLT generale si trova nel file "LocalState/frozenWorldState.hkfw". Una volta creato da WLT, tale file può essere copiato in un'altra posizione e ripristinato a discrezione dell'applicazione.

Per impostazione predefinita, il file di salvataggio per i dati di allineamento (SpacePin) è "LocalState/Persistence/Alignment.fwb". È tuttavia possibile eseguire l'override dell'applicazione tramite SaveFileName del gestore di allineamento.

La decisione di caricare lo stato della sessione precedente con questa configurazione deve essere presa all'avvio. Dopo aver eseguito lo stato salvato della sessione precedente, verrà sovrascritto con lo stato di questa sessione. Per una configurazione più flessibile, vedere Salvataggio e caricamento manuali di seguito.

Salvataggio manuale ma caricamento automatico

Impostazioni per il caricamento automatico ma il salvataggio controllato dall'applicazione

In questa configurazione, WLT caricherà qualsiasi stato disponibile da una sessione precedente all'avvio. Tuttavia, non salverà automaticamente lo stato. Ciò consente all'applicazione di decidere se e quando lo stato vale la pena salvare, con una chiamata a Save().

Il caricamento automatico indica solo a WLT di caricare qualsiasi stato disponibile all'avvio. L'applicazione è libera di ripristinare qualsiasi stato salvato in qualsiasi momento con una chiamata esplicita a Load().

Salvataggio e caricamento manuali

Impostazioni senza persistenza o persistenza controllata dall'applicazione

L'applicazione può scegliere di mantenere il controllo totale sul processo di salvataggio e caricamento.

Lo stato verrà quindi salvato solo con una chiamata esplicita dall'applicazione a Save() e caricato solo con una chiamata esplicita a Load().State will then be saved with an explicit call from the application to Save() and only loaded with an explicit call to Load().

Lo stato caricato dalla chiamata a Load() potrebbe essere stato salvato in precedenza in questa sessione o in una sessione precedente.

Disabilitazione della persistenza

Come spiegato in precedenza, la persistenza è sempre disponibile per l'applicazione dallo script. La persistenza automatizzata può essere abilitata e disabilitata dallo script o tramite WorldLockingContext nel controllo. Se la persistenza automatica è disabilitata, WLT non tenterà di salvare o caricare lo stato senza richieste esplicite dall'applicazione.

Naturalmente, poiché la direttiva AutoLoad influisce solo sul caricamento o meno all'avvio, la modifica del valore dallo script dopo l'avvio non ha alcun effetto.

Attenzione durante lo sviluppo

Come indicato in precedenza, il percorso dei file di salvataggio per il WLT globale e l'allineamento sono globali per l'applicazione. In particolare, i nodi di allineamento, noti anche come Puntini spazi, vengono mantenuti in base al nome (vedere di seguito). Se un'applicazione salva lo stato con un set di Puntini spazi da una scena e quindi carica lo stato con un set di Puntini spazi da un'altra scena e entrambi i set di SpaziPin condividono nomi comuni, il comportamento non è definito.

Esistono diversi modi per risolvere questo problema. Se possibile, è consigliabile evitare semplicemente di riutilizzare i nomi di SpacePin all'interno di un progetto. Se dopo la ri-distribuzione viene visualizzato un comportamento imprevisto di scorrimento della scena, provare a eliminare lo stato di salvataggio WLT. Analogamente, quando si modifica radicalmente l'applicazione, l'eccessivamente prudente potrebbe voler eliminare i file WLT salvando i file dal dispositivo o semplicemente disinstallare l'applicazione prima di installare la nuova versione.

Persistenza in base alla posizione

Scenario

Esiste una classe interessante di applicazioni eseguite in più posizioni fisiche. L'applicazione potrebbe essere eseguita nella sala A, il dispositivo chiuso, rilocato e quindi l'applicazione riavviata nella sala B. La sala B potrebbe essere inattiva dalla sala A o potrebbe trovarsi in un altro continente. L'applicazione e il dispositivo non hanno modo di sapere.

Per semplicità, si supponga che l'applicazione sia configurata per la persistenza WLT manuale.

Procedura dettagliata

Considera queste camere non connesse A e B.

Stanze vuote in diversi continenti

L'applicazione viene avviata nella sala A. Dopo aver stabilito uno spazio di coordinate bloccato contiguo all'interno della stanza, l'intera stanza esegue il mapping al frammento 1. Un oggetto X ologramma permanente viene posizionato nella stanza. L'applicazione salva quindi lo stato e viene chiuso.

Sala di chiusura del mondo A.

Il dispositivo viene spento, portato in Sala B e avviato di nuovo.

Il dispositivo riconosce che non è Room A, quindi WLT assegna un nuovo ID frammento al relativo contenuto, ad esempio ID == 29. Perché 29? Perché non è 1. Gli ID frammento sono arbitrari in valore, ad eccezione dell'ID di un frammento non sarà FragmentId.Invalid o FragmentId.Unknown o uguale a qualsiasi altro frammento noto.

Sala di chiusura del mondo B con camera A non tracciata

Ora ci sono due frammenti e non è possibile unirli (poiché non sono disponibili informazioni sulle posizioni relative).

Lo sviluppatore di applicazioni interessato potrebbe chiedere: È stato inserito un oggetto persistente X nella sala A, cosa accade quando l'oggetto X viene caricato all'avvio dell'applicazione nella sala B?

La risposta è che il comportamento viene lasciato allo sviluppatore dell'applicazione per determinare. ID frammento corrente quando l'oggetto X viene posizionato nella sala A è disponibile e può essere salvato in modo permanente. L'applicazione può quindi decidere all'avvio se mostrare o meno l'oggetto X in base al fatto che il frammento corrente sia uguale a quando è stato creato o meno.

In questo caso, lo sviluppatore decide (e implementa) che Object X verrà caricato solo se l'ID frammento corrente è uno e Object Y, dalla sala B, verrà caricato solo se il frammento corrente è 29.

La persistenza dell'ID frammento associato a uno spazio viene salvata come parte della persistenza di World Locking Tools. Tuttavia, la persistenza dell'ID frammento associato a un oggetto, nonché le azioni da eseguire in base a essa, vengono lasciate all'applicazione.

Insieme all'ID frammento associato dell'oggetto, è possibile salvare la relativa posizione nello spazio globale. Quindi, se l'ID frammento corrisponde, dopo che l'oggetto viene caricato, è possibile ripristinarne la posizione nel mondo fisico durante l'ultima sessione. Con la persistenza degli strumenti di blocco globale, una pose rimane fissa tra le sessioni rispetto alle funzionalità del mondo fisico intorno a esso.

Persistenza delle puntine spaziatrice

SpacePins può essere considerato come wrapper sul lato applicazione per AlignmentAnchors. Mentre SpacePins (e le classi derivate) sono componenti unity, AlignmentAnchors sono puramente concettuali; non esiste una classe o un tipo corrispondente a alignmentAnchor. Pertanto, in questa discussione, SpacePins e AlignmentAnchors verranno usati in modo intercambiabile, con una preferenza generale per SpacePins.

Tuttavia, potrebbe in caso contrario confondere che un AlignmentManager può rendere persistenti Le puntine spaziatrice, quando non ha alcuna nozione di Puntini spazi. Ciò è dovuto al fatto che AlignmentManager gestisce il concetto AlignmentAnchor, che incarna l'essenza di una SpacePin e da cui è possibile ricostituire un elemento SpacePin.

Sono disponibili più controlli a livello di applicazione per la persistenza di SpacePins rispetto al sistema di persistenza WLT generale, perché SpacePins è intrinsecamente più guidato dall'input dell'applicazione rispetto al resto degli strumenti di blocco globale.

È importante ricordare che SpacePins (e AlignmentAnchors) vengono mantenuti in base al nome. Si tratta di un requisito leggermente più forte rispetto a quello generale che non due SpacePin attivi nello stesso IAlignmentManager hanno lo stesso nome. Se si rende persistente SpacePins, non è possibile che due Puntini spazi nello stesso database abbiano lo stesso nome, se attivo o meno.

Database di Gestione allineamento

Ogni IAlignmentManager ha un database di SpacePins in base al nome, come implicito nell'implementazione di RestoreAlignmentAnchor(string uniqueName, Pose virtualPose).

Database di allineamento globale

Esiste un oggetto IAlignmentManager globale, di proprietà di WorldLockingManager.GetInstance(). Come accennato, il percorso predefinito del file di salvataggio è determinato dalla proprietà SaveFileName. Si noti che SaveFileName è una proprietà sulla classe AlignmentManager, non sull'interfaccia IAlignmentManager. Un'implementazione di IAlignmentManager potrebbe implementare la persistenza senza alcun concetto di file o nomi file. SaveFileName è un artefatto del modo in cui AlignmentManager implementa la persistenza e quindi è limitato a AlignmentManager.

Database di allineamento locale

Può essere presente un numero qualsiasi di gestori di allineamento dello spazio secondario, uno per ogni alignSubtree, visualizzato come campo AlignSubtree.alignmentManager. Inoltre, l'applicazione può creare le proprie istanze di AlignmentManager o persino le proprie classi derivate da IAlignmentManager.

Ogni elemento AlignmentManager del componente AlignSubtree ha il proprio percorso di salvataggio del file, che per impostazione predefinita corrisponde al nome del GameObject, con l'estensione ".fwb". Ad esempio, se il componente AlignSubtree si trova in un GameObject denominato "MyRoot", il file di salvataggio sarà denominato "MyRoot.fwb". Una barra '/' può essere usata per inserirla in una sottocartella. È probabile che due componenti AlignSubtree usino lo stesso percorso del file di salvataggio.

Ma davvero

È fortemente consigliabile che, a lungo termine, sia più semplice e affidabile fornire nomi univoci di SpacePins/AlignmentAnchors a livello globale, piuttosto che provare a gestire il requisito più leggero univoco in locale. Ma fai quello che ti piace.

Vedi anche