Compartilhar via


Truques de persistência

A persistência está disponível quando for compatível com a plataforma subjacente. Atualmente, isso está limitado à família de dispositivos HoloLens usando o suporte a VR integrado do Unity (XR Herdada).

Persistência básica

A persistência básica do World Locking Tools é habilitada por padrão. Essa habilitação é feita em duas partes.

Configurações do inspetor para persistência

As caixas de seleção relevantes são "Auto Load" e "Salvamento Automático", que estão marcadas. Observe que elas estão acinzentadas, pois elas fazem parte da escolha "Usar padrões". Ao desabilitar "Usar padrões", é possível selecionar combinações arbitrárias das opções de Automação.

Leitura adicional está disponível nessas configurações e em como manipulá-las do script.

Salvamento Automático

A opção de Salvamento Automático direciona o WLT para salvar o estado de forma frequente e regular durante a execução do aplicativo. O aplicativo pode ser encerrado a qualquer momento com perda mínima de estado.

AutoLoad

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

Persistência completa

Com o AutoSave e o Carregamento Automático habilitados, o WLT opera perfeitamente entre as sessões. Embora a posição e a orientação do espaço global sejam arbitrárias na primeira execução (já que não há nenhum estado anterior salvo, ele usa a pose de cabeça na inicialização como a origem), as próximas execuções irão compartilhar esse mesmo quadro de coordenadas.

Isso causa 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.

Observação

As configurações AutoSave e Carregamento Automático também se aplicam a SpacePins globais. Veja abaixo para obter mais detalhes.

Controle do aplicativo sobre persistência

A persistência completa padrão é adequada para diversos aplicativos.

No entanto, alguns aplicativos podem querer um controle mais refinado sobre o processo.

Pode parecer estranho que a habilitação da persistência automática do WLT seja dividida em duas propriedades: AutoSave e Carregamento Automático. O exame de casos onde os dois são usados de forma independente pode fornecer insights sobre o sistema de persistência geral.

AutoSave, mas não Carregamento Automático

Configuração para salvamento automático, mas carregamento controlado por aplicativos

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

Em vez disso, o sistema será iniciado em um estado novo, como se fosse a primeira vez que ele é 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 seria apropriado restaurar o estado da sessão anterior e até mesmo modificar os dados que estão sendo restaurados, se necessário.

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

O padrão do arquivo de salvamento para dados de alinhamento (SpacePin) é "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. Após a execução, o estado salvo da sessão anterior será substituído pelo estado dessa sessão. Para obter uma configuração mais flexível, consulte Salvamento e carregamento manual abaixo.

Salvar manualmente, mas Carregamento Automático

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

Nessa configuração, o WLT carregará qualquer estado disponível de uma sessão anterior na inicialização. No entanto, ele 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 Carregamento Automático apenas informa ao WLT para carregar qualquer estado disponível na inicialização. O aplicativo fica livre para restaurar qualquer estado salvo a qualquer momento com uma chamada explícita para Load().

Salvamento e carregamento manual

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 carregado apenas 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.

Como desabilitar a persistência

Conforme explicado acima, a persistência está sempre disponível para o aplicativo por meio do script. A persistência automatizada pode ser habilitada e desabilitada no script ou através do WorldLockingContext no Inspector. Se a persistência automatizada estiver desabilitada, o WLT não tentará salvar ou carregar o estado sem solicitações explícitas do aplicativo.

É claro que, como a diretiva de Carregamento Automático afeta apenas se o carregamento deve ser feito inicialização, a alteração do valor do script após a inicialização não terá efeito.

Um cuidado durante o desenvolvimento

Conforme indicado acima, o local para salvar os arquivos para o 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 salvar o estado com um conjunto de SpacePins de uma cena e, em seguida, carregar o estado com um conjunto de SpacePins de outra cena e ambos os conjuntos de SpacePins compartilharem nomes comuns, o comportamento será indefinido.

Há várias maneiras em torno desse problema. Se possível, o melhor é simplesmente evitar a reutilização de nomes do SpacePin em um projeto. Se, após a re-implantação, um comportamento deslizante de cena inesperado for apresentado, tente excluir o estado salvo do WLT. Da mesma forma, ao alterar radicalmente o aplicativo, o excesso de cuidado pode querer excluir seus arquivos de salvamento do WLT do dispositivo ou simplesmente desinstalar o aplicativo antes de instalar a nova versão.

Persistência por local

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 hall da Sala A ou em outro continente. O aplicativo e o dispositivo não têm como saber.

Para simplificar, digamos que o aplicativo está configurado para persistência do WLT manual.

Um passo a passo

Considere as salas não conectadas A e B.

Quartos vazios em diferentes continentes

O aplicativo é iniciado na Sala A. Depois de estabelecer um espaço de coordenada congelado contíguo na sala, toda a sala é mapeada para o fragmento 1. Um Objeto X de holograma persistente é posicionado 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 iniciado novamente.

O dispositivo reconhece que isso não é a Sala A, portanto, o WLT atribui uma nova ID de fragmento ao seu conteúdo, digamos, ID == 29. Por quê 29? Porque não é 1. IDs de fragmento possuem valor arbitrário, diferente da ID de um fragmento não serão FragmentId.Invalid ou FragmentId.Unknown ou a mesma que qualquer outro fragmento conhecido.

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

Agora há dois fragmentos e nenhuma maneira de mesclá-los (já que não há informações disponíveis em seus locais relativos).

O desenvolvedor de aplicativos interessado pode perguntar: eu posicionei 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 é determinado pelo desenvolvedor do aplicativo. A ID de fragmento atual quando o Objeto X é colocado na Sala A está disponível e pode ser persistida. Em seguida, o aplicativo pode decidir na inicialização se deve ou não mostrar o Objeto X com base em se o fragmento atual é o mesmo de quando ele foi criado ou não.

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

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

Juntamente com a ID de fragmento associada do objeto, sua Pose no espaço global pode ser salva. Em seguida, se a ID do fragmento corresponde, depois que o objeto é carregado, sua Pose pode ser restaurada, retornando-a para sua posição no mundo físico durante a última sessão. Com a persistência do World Locking Tools, uma Pose permanece fixa entre as sessões em relação aos recursos do mundo físico ao seu redor.

Persistência de SpacePins

SpacePins podem ser considerados como wrappers do lado do aplicativo para AlignmentAnchors. Enquanto SpacePins (e classes derivadas) são componentes do 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 para SpacePins.

No entanto, pode ser confuso o fato de um AlignmentManager poder persistir SpacePins quando não tiver nenhuma noção de SpacePins. Isso ocorre porque o AlignmentManager gerencia o AlignmentAnchor conceitual, que incorpora a essência de um SpacePin e 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 geral de persistência do WLT, pois SpacePins são inerentemente mais controlados por entrada de aplicativo do que o World Locking Tools.

É importante lembrar que SpacePins (e AlignmentAnchors) são persistidos por nome. Esse é um requisito um pouco mais forte do que o geral de que dois SpacePins ativos no mesmo IAlignmentManager têm o mesmo nome. Se os SpacePins forem persistentes, dois SpacePins no mesmo banco de dados não podem ter o mesmo nome, estando ativos 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).

O banco de dados de alinhamento global

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

Bancos de dados de alinhamento local

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

Cada AlignmentManager do componente AlignSubtree tem seu próprio local de arquivo de salvamento, que usa 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 de salvamento seria nomeado "MyRoot.fwb". Uma barra "/" pode ser usada para colocá-lo em uma subpasta. Provavelmente, seria ruim para dois componentes AlignSubtree usarem o mesmo local de arquivo de salvamento.

Na verdade

É recomendável que, a longo prazo, seja mais simples e mais robusto fornecer nomes exclusivos SpacePins/AlignmentAnchors globalmente, do que tentar gerenciar o requisito exclusivo local mais leve. Mas faça o que você desejar.

Confira também