Partilhar via


Truques de persistência

A persistência está disponível quando suportada pela plataforma subjacente. Atualmente, isso é limitado à família de dispositivos HoloLens, usando o suporte VR integrado do Unity (Legacy XR).

Persistência básica

A persistência básica para World Locking Tools vem ativada por padrão. Esta habilitação vem em duas partes.

Configurações do inspetor para persistência

As caixas de seleção relevantes aqui são "Auto Load" e "Auto Save", que estão marcadas. Você pode notar que eles estão acinzentados. Isso porque eles fazem parte da opção "Usar padrões". A desativação de "Usar padrões" permite a seleção de combinações arbitrárias das opções de automação.

Leitura adicional está disponível sobre essas configurações, e sobre como manipulá-los a partir do script.

AutoSave

A opção AutoSave direciona o WLT para fazer salvamentos de estado frequentes e regulares durante a execução do aplicativo. A qualquer momento, o pedido pode ser encerrado com perda mínima de estado.

Carregamento Automático

A opção AutoLoad direciona o WLT para carregar qualquer estado salvo anteriormente na inicialização. Isso efetivamente permite que o aplicativo retome uma nova sessão de onde parou (w.r.t. WLT) da última sessão.

Persistência total

Com o AutoSave e o AutoLoad ativados, o WLT funciona perfeitamente em todas as sessões. Embora a posição e a orientação do espaço global sejam arbitrárias na primeira execução (uma vez que não há nenhum estado anterior salvo, ele usa a pose de cabeça na inicialização como origem), as execuções subsequentes compartilharão esse mesmo quadro de coordenadas.

Isso leva a um comportamento interessante quando o aplicativo inicia uma nova sessão em um espaço desconectado do espaço da sessão anterior. Consulte a seção persistência por local abaixo para obter detalhes.

Nota

As configurações de Salvamento Automático e Carregamento Automático também se aplicam aos SpacePins globais. Veja mais detalhes abaixo .

Controle de aplicativos sobre persistência

A persistência total padrão é adequada para uma ampla gama de aplicativos.

Alguns aplicativos, no entanto, podem querer um controle mais fino sobre o processo.

Pode parecer estranho que a ativação da persistência automática WLT seja dividida em duas propriedades, o AutoSave e o AutoLoad. Examinar casos em que os dois são usados de forma independente pode fornecer informações sobre o sistema geral de persistência.

Gravação Automática, mas não Carregamento Automático

Configuração para salvamento automático, mas carregamento controlado pelo aplicativo

Com essa configuração, o WLT é definido para salvar periodicamente seu estado. No entanto, ele não carregará automaticamente nenhum estado persistente na inicialização.

Em vez disso, o sistema começará em um novo estado, como se fosse a primeira vez sendo executado neste dispositivo. Somente após uma solicitação explícita para Load() ele restaurará o estado da sessão anterior.

Isso permite que o aplicativo decida se a restauração do estado da sessão anterior seria apropriada ou não, e até mesmo modifique os dados que estão sendo restaurados, se necessário.

O estado geral de salvamento WLT está no arquivo "LocalState/frozenWorldState.hkfw". Uma vez criado pela WLT, esse arquivo pode ser copiado para outro local e restaurado de volta a critério do aplicativo.

O arquivo salvo para dados de alinhamento (SpacePin) tem como padrão "LocalState/Persistence/Alignment.fwb". No entanto, isso pode ser substituído pelo aplicativo por meio do SaveFileName do gerenciador de alinhamento.

A decisão de carregar o estado da sessão anterior com essa configuração precisa ser tomada na inicialização. Uma vez executado, o estado salvo da sessão anterior será substituído pelo estado desta sessão. Para uma configuração mais flexível, consulte Salvar e carregar manual abaixo.

Salvar manualmente, mas AutoLoad

Configurações para carregamento automático, mas salvamento controlado pelo aplicativo

Nessa configuração, o WLT carregará qualquer estado disponível de uma sessão anterior na inicialização. No entanto, não salvará automaticamente o estado. Isso permite que o aplicativo decida se e quando vale a pena salvar o estado, com uma chamada para Save().

O AutoLoad apenas diz ao WLT para carregar qualquer estado disponível na inicialização. O aplicativo é livre para restaurar qualquer estado salvo a qualquer momento com uma chamada explícita para Load().

Guardar e carregar manualmente

Configurações para nenhuma persistência ou persistência controlada pelo aplicativo

O aplicativo pode optar por manter o controle total sobre o processo de salvar e carregar.

O estado só será salvo com uma chamada explícita do aplicativo para Save(), e somente carregado com uma chamada explícita para Load().

O estado carregado pela chamada para Load() pode ter sido salvo anteriormente nesta sessão ou em uma sessão anterior.

Desativando a persistência

Como explicado acima, a persistência está sempre disponível para o aplicativo a partir do script. A persistência automatizada pode ser habilitada e desabilitada a partir do script ou por meio do WorldLockingContext no Inspetor. Se a persistência automatizada estiver desativada, o WLT não fará nenhuma tentativa de salvar ou carregar o estado sem solicitações explícitas do aplicativo.

É claro que, como a diretiva AutoLoad afeta apenas se deve ou não carregar na inicialização, alterar o valor do script após a inicialização não tem efeito.

Uma precaução durante o desenvolvimento

Como observado acima, o local dos arquivos salvos para WLT global e alinhamento são globais para o aplicativo. Em particular, os nós de alinhamento, também conhecidos como SpacePins, são persistentes pelo nome (veja abaixo). Se um aplicativo salva o estado com um conjunto de SpacePins de uma cena e, em seguida, carrega o estado com um conjunto de SpacePins de outra cena, e ambos os conjuntos de SpacePins compartilham nomes comuns, então o comportamento é indefinido.

Há várias maneiras de contornar esse problema. Se possível, o melhor é simplesmente evitar a reutilização de nomes SpacePin dentro de um projeto. Se, após a reimplantação, você vir um comportamento inesperado de deslizamento de cena, tente excluir o estado de salvamento WLT. Da mesma forma, ao alterar radicalmente o aplicativo, os excessivamente cautelosos podem querer excluir seus arquivos de salvamento WLT do dispositivo ou simplesmente desinstalar o aplicativo antes de instalar a nova versão.

Persistência por localização

Cenário

Há uma classe interessante de aplicativos que são executados em vários locais físicos. O aplicativo pode ser executado na Sala A, o dispositivo fechado, realocado e, em seguida, o aplicativo reiniciado na Sala B. A Sala B pode estar no corredor da Sala A ou pode estar em outro continente. O aplicativo e o dispositivo não têm como saber.

Para simplificar, digamos que o aplicativo esteja configurado para persistência WLT manual.

Um passo a passo

Considere estes quartos A e B desconectados.

Quartos vazios em diferentes continentes

O pedido é iniciado na Sala A. Depois de estabelecer um espaço de coordenadas congeladas contíguo dentro da sala, toda a sala mapeia para o fragmento 1. Um holograma persistente Objeto X é colocado na sala. Em seguida, o aplicativo salva o estado e é encerrado.

Quarto de bloqueio mundial A.

O dispositivo é desligado, levado para a sala B e reiniciado.

O dispositivo reconhece que esta não é a Sala A, por isso a WLT atribui um novo ID de fragmento ao seu conteúdo, digamos ID == 29. Porquê 29? Porque não é 1. IDs de fragmento são arbitrárias em valor, diferente de um ID de fragmento não será FragmentId.Invalid, ou FragmentId.Unknown, ou o mesmo que qualquer outro fragmento conhecido.

Quarto de bloqueio mundial B com quarto A não rastreado

Agora há dois fragmentos, e não há como mesclá-los (uma vez que não há informações disponíveis sobre suas localizações relativas).

O desenvolvedor de aplicativos interessado pode perguntar: Eu coloquei um Objeto X persistente na Sala A, o que acontece quando o Objeto X é carregado quando o aplicativo é iniciado na Sala B?

A resposta é que o comportamento é deixado para o desenvolvedor do aplicativo para determinar. A ID do fragmento atual quando o Objeto X é colocado na Sala A está disponível e pode ser persistida. O aplicativo pode então decidir na inicialização se mostra o Objeto X ou não com base em se o fragmento atual é o mesmo de quando foi criado ou não.

Aqui, o desenvolvedor decide (e implementa) que o Objeto X só será carregado se o ID do fragmento atual for um, e o Objeto Y, da Sala B, só será carregado se o fragmento atual for 29.

A persistência do ID do fragmento associado a um espaço é salva como parte da persistência das Ferramentas de Bloqueio Mundial. No entanto, a persistência do ID do fragmento associado a um objeto, bem como as ações a serem tomadas com base nele, são deixadas para o aplicativo.

Junto com o ID de fragmento associado ao objeto, sua pose no espaço global pode ser salva. Em seguida, se o ID do fragmento corresponder, depois que o objeto for carregado, seu Pose poderá ser restaurado, retornando-o à sua posição no mundo físico durante a última sessão. Com a persistência do World Locking Tools, um Pose permanece fixo nas sessões em relação aos recursos do mundo físico ao seu redor.

Persistência de SpacePins

Os SpacePins podem ser pensados como wrappers do lado do aplicativo para AlignmentAnchors. Enquanto SpacePins (e classes derivadas) são componentes Unity, AlignmentAnchors são puramente conceituais; não há nenhuma classe ou tipo correspondente a um AlignmentAnchor. Portanto, nesta discussão, SpacePins e AlignmentAnchors serão usados de forma intercambiável, com uma preferência geral por SpacePins.

No entanto, pode ser confuso que um AlignmentManager possa persistir SpacePins, quando ele não tem noção de SpacePins. Isso ocorre porque o AlignmentManager gerencia o AlignmentAnchor conceitual, que incorpora a essência de um SpacePin, e a partir do qual um SpacePin pode ser reconstituído.

Há mais controles de nível de aplicativo para a persistência de SpacePins do que com o sistema de persistência WLT geral, porque os SpacePins são inerentemente mais orientados pela entrada de aplicativos do que o resto das Ferramentas de Bloqueio Mundial.

É importante lembrar que SpacePins (e AlignmentAnchors) são persistentes pelo nome. Este é um requisito um pouco mais forte do que o geral de que não há dois SpacePins ativos no mesmo IAlignmentManager têm o mesmo nome. Se persistir SpacePins, então não há dois SpacePins no mesmo banco de dados pode ter o mesmo nome, se ativo ou não.

Bancos de dados do gerenciador de alinhamento

Cada IAlignmentManager tem um banco de dados de SpacePins por nome, como implícito por sua implementação de RestoreAlignmentAnchor(string uniqueName, Pose virtualPose).

A base de dados de alinhamento global

Há um IAlignmentManager global, de propriedade do WorldLockingManager.GetInstance(). Como mencionado, seu local de arquivo de salvamento padrão é determinado pela propriedade SaveFileName. Observe que o SaveFileName é uma propriedade na classe AlignmentManager, não a interface IAlignmentManager. Uma implementação IAlignmentManager pode implementar persistência sem qualquer conceito de arquivos ou nomes de arquivos. O SaveFileName é um artefato da maneira como o AlignmentManager implementa a persistência e, portanto, é restrito ao AlignmentManager.

Bases de dados de alinhamento local

Pode haver qualquer número de gerenciadores de alinhamento de subespaço, um para cada AlignSubtree, aparecendo como o campo AlignSubtree.alignmentManager. Além disso, o aplicativo pode criar suas próprias instâncias AlignmentManager ou até mesmo suas próprias classes derivadas de IAlignmentManager.

O AlignmentManager de cada componente AlignSubtree tem seu próprio local de arquivo salvo, que assume como padrão o nome do GameObject, com a extensão ".fwb". Por exemplo, se o componente AlignSubtree estiver em um GameObject chamado "MyRoot", o arquivo salvo será chamado "MyRoot.fwb". Uma barra '/' pode ser usada para colocá-lo em uma subpasta. Provavelmente seria ruim para dois componentes do AlignSubtree usar o mesmo local de salvar o arquivo.

Mas realmente

É altamente recomendável que, a longo prazo, seja mais simples e robusto dar nomes globalmente exclusivos ao SpacePins/AlignmentAnchors do que tentar gerenciar o requisito localmente mais leve e exclusivo. Mas faça o que quiser.

Consulte também