Fazer com que seus hologramas permaneçam no lugar, se movam com você ou, em alguns casos, se posicionem em relação a outros hologramas é uma grande parte da criação de aplicativos de Realidade Misturada. Este artigo mostrará nossa solução recomendada usando as Ferramentas de Bloqueio Mundial, mas também abordaremos a configuração manual de âncoras espaciais em seus projetos do Unity. Antes de entrarmos em qualquer código, é importante entender como o Unity lida com o espaço de coordenadas e âncoras em seu próprio mecanismo.
Sistemas de coordenadas em escala mundial
Hoje, ao escrever jogos, aplicativos de visualização de dados ou aplicativos de realidade virtual, a abordagem típica é estabelecer um sistema de coordenadas mundial absoluto para o qual todas as outras coordenadas possam mapear de forma confiável. Nesse ambiente, você sempre pode encontrar uma transformação estável que define uma relação entre dois objetos nesse mundo. Se você não movesse esses objetos, suas transformações relativas permaneceriam sempre as mesmas. Esse tipo de sistema de coordenadas global é fácil de acertar ao renderizar um mundo puramente virtual onde você conhece toda a geometria com antecedência. Os aplicativos de RV em escala de sala hoje normalmente estabelecem esse tipo de sistema de coordenadas absoluto em escala de sala com sua origem no chão.
Por outro lado, um dispositivo de realidade misturada sem restrições, como o HoloLens, tem uma compreensão dinâmica do mundo orientada por sensores, ajustando continuamente seu conhecimento ao longo do tempo sobre os arredores do usuário à medida que ele caminha muitos metros por um andar inteiro de um edifício. Em uma experiência em escala mundial, se você colocasse todos os seus hologramas em um sistema de coordenadas rígido ingênuo, esses hologramas acabariam se desviando ao longo do tempo, com base no mundo ou em relação uns aos outros.
Por exemplo, o fone de ouvido pode atualmente acreditar que dois locais no mundo estão a 4 metros de distância e, posteriormente, refinar esse entendimento, aprendendo que os locais estão de fato a 3,9 metros de distância. Se esses hologramas tivessem sido inicialmente colocados a 4 metros de distância em um único sistema de coordenadas rígidas, um deles sempre apareceria a 0,1 metros do mundo real.
Você pode colocar manualmente âncoras espaciais no Unity para manter a posição de um holograma no mundo físico quando o usuário é móvel. No entanto, isso sacrifica a autoconsistência dentro do mundo virtual. Diferentes âncoras estão constantemente se movendo em relação umas às outras e também estão se movendo através do espaço de coordenadas global. Nesse cenário, tarefas simples como layout tornam-se difíceis. A simulação de física também pode ser problemática.
O World Locking Tools (WLT) oferece o melhor dos dois mundos, estabilizando um único sistema de coordenadas rígidas usando um suprimento interno de âncoras espaciais espalhadas por toda a cena virtual à medida que o usuário se move. O WLT analisa as coordenadas da câmera e essas âncoras espaciais a cada quadro. Em vez de alterar as coordenadas de tudo no mundo para compensar as correções nas coordenadas da cabeça do usuário, o WLT apenas corrige as coordenadas da cabeça.
Escolha sua abordagem de bloqueio mundial
Se possível, use as Ferramentas de Bloqueio Mundial para posicionamento do holograma.
As ferramentas de bloqueio mundial fornecem um sistema de coordenadas estável que minimiza as inconsistências visíveis entre os marcadores do mundo virtual e real. As Ferramentas de Bloqueio Mundial bloqueiam toda a cena com um conjunto compartilhado de âncoras, em vez de bloquear cada grupo de objetos com a própria âncora individual do grupo.
O World Locking Tools lida automaticamente com a criação e o gerenciamento internos de âncoras espaciais. Você não precisa interagir com ARAnchorManager ou WorldAnchor para manter seus hologramas bloqueados pelo mundo.
Para o Unity 2019/2020 usando o OpenXR ou o plug-in do Windows XR, use ARAnchorManager.
Para versões mais antigas do Unity ou projetos WSA, use o WorldAnchor.
Para começar a usar as Ferramentas de Bloqueio Mundial, baixe a Ferramenta de Recursos de Realidade Misturada. Para saber mais sobre as noções básicas, consulte a página principal da documentação do World Locking Tools para obter links para Visão geral, Início rápido e outros tópicos úteis.
Quando o projeto estiver pronto, execute o utilitário de configuração de cena de Realidade > Misturada Ferramentas de Bloqueio Mundial:
Importante
O utilitário Configurar cena pode ser reexecutado a qualquer momento. Por exemplo, ele deverá ser reexecutado se o destino de RA tiver sido alterado de Herdado para SDK do XR. Se a cena já estiver configurada corretamente, a execução do utilitário não terá efeito.
Visualizadores
Durante o desenvolvimento inicial, a adição de visualizadores pode ser útil para garantir que o WLT esteja configurado e funcionando corretamente. Eles podem ser removidos para desempenho de produção ou, se por algum motivo não forem mais necessários, usando o utilitário Remover visualizadores. Mais detalhes sobre os visualizadores podem ser encontrados na documentação de Ferramentas.
O plug-in OpenXR de realidade misturada fornece funcionalidade básica de âncora por meio de uma implementação do ARFoundation ARAnchorManager do Unity. Para aprender o básico sobre ARAnchors em ARFoundation, visite o Manual de ARFoundation para AR Anchor Manager.
Namespace:UnityEngine.XR.WSA Tipo:WorldAnchor
Uma técnica importante é criar uma âncora espacial para bloquear um cluster de hologramas precisamente no lugar no mundo físico, não importa o quão longe o usuário tenha percorrido, e localizar esses hologramas novamente em sessões posteriores.
Em versões mais antigas do Unity, você cria uma âncora espacial adicionando o componente WorldAnchor Unity a um GameObject.
Adicionar uma âncora mundial
Para adicionar uma âncora de mundo, chame AddComponent<WorldAnchor>() o objeto de jogo com a transformação que você deseja ancorar no mundo real.
Este objeto de jogo agora está ancorado em sua localização atual no mundo físico. Você pode ver suas coordenadas mundiais do Unity se ajustarem um pouco ao longo do tempo para garantir o alinhamento físico. Consulte carregar uma âncora mundial para encontrar esse local ancorado novamente em uma sessão de aplicativo futura.
Remover uma âncora mundial
Se você não quiser mais o GameObject bloqueado para um local físico do mundo e não pretende movê-lo para este quadro, chame Destroy o componente Âncora do mundo.
Destroy(gameObject.GetComponent<WorldAnchor>());
Se você quiser mover este GameObject quadro, chame DestroyImmediate em vez disso.
Uma Âncora Mundial pode não ser localizável no mundo físico em um determinado momento. Em seguida, o Unity não atualizará a transformação do objeto ancorado. Essa situação também pode acontecer enquanto um aplicativo está em execução. A falha em lidar com a mudança na localização faz com que o objeto não apareça no local físico correto no mundo.
Para ser notificado sobre alterações de localização:
Inscreva-se no OnTrackingChanged evento. O OnTrackingChanged evento é chamado sempre que a âncora espacial subjacente muda entre um estado de ser localizável ou não localizável.
private void Anchor_OnTrackingChanged(WorldAnchor self, bool located)
{
// This simply activates/deactivates this object and all children when tracking changes
self.gameObject.SetActiveRecursively(located);
}
Se as âncoras estiverem localizadas imediatamente, a isLocated propriedade da âncora será definida como true quando AddComponent<WorldAnchor>() retornar. Portanto, o OnTrackingChanged evento não é disparado. Um padrão mais limpo é chamar o OnTrackingChanged manipulador com o estado inicial IsLocated depois de anexar uma âncora.
As âncoras espaciais salvam hologramas no espaço do mundo real entre as sessões do aplicativo. Depois de salvas no repositório de âncoras do HoloLens, as âncoras espaciais podem ser encontradas e carregadas em sessões diferentes e são um fallback ideal quando não há conectividade com a Internet.
Importante
As âncoras locais são armazenadas no dispositivo, enquanto as Âncoras Espaciais do Azure são armazenadas na nuvem. Você pode ter âncoras locais e do Azure no mesmo projeto sem conflito. Para obter mais informações sobre como integrar os serviços de nuvem do Azure para armazenar suas âncoras, consulte Âncoras Espaciais do Azure.
Por padrão, as Ferramentas de Bloqueio Mundial restauram o sistema de coordenadas do Unity em relação ao mundo físico em sessões em dispositivos que dão suporte à persistência de âncoras espaciais locais. Para que um holograma apareça no mesmo local no mundo físico depois de sair e executar novamente o aplicativo, o aplicativo só precisa restaurar a mesma pose para o holograma.
Se o aplicativo precisar de um controle mais preciso, você poderá desabilitar o Salvamento Automático e o Carregamento Automático no inspetor e gerenciar a persistência de um script. Para obter mais informações, consulte Persistir sistemas de coordenadas espaciais.
As Ferramentas de Bloqueio Mundial dão suporte à persistência de âncora local somente em dispositivos HoloLens. Para dispositivos Android, iOS e HoloLens, integre-se às Âncoras Espaciais do Azure para dar suporte à persistência e ao compartilhamento de espaços de coordenadas entre sessões e dispositivos. Para obter mais informações e exemplos usando as Ferramentas de Bloqueio Mundial com as Âncoras Espaciais do Azure, consulte WLT (Ferramentas de Bloqueio Mundial) combinadas com as Âncoras Espaciais do Azure (ASA).
Uma API chamada XRAnchorStore permite que as âncoras sejam mantidas entre as sessões. O XRAnchorStore é uma representação das âncoras salvas em um dispositivo. Você pode persistir âncoras na cena do ARAnchors Unity, carregar âncoras do armazenamento em new ARAnchorsou excluir âncoras do armazenamento.
Observação
Você salva e carrega essas âncoras no mesmo dispositivo. Há suporte para âncoras entre dispositivos por meio das Âncoras Espaciais do Azure.
Namespaces
Para Unity 2020 e OpenXR:
using Microsoft.MixedReality.ARSubsystems.XRAnchorStore
ou Unity 2019/2020 + Plug-in do Windows XR:
using UnityEngine.XR.WindowsMR.XRAnchorStore
Métodos públicos
{
// A list of all persisted anchors, which can be loaded.
public IReadOnlyList<string> PersistedAnchorNames { get; }
// Clear all persisted anchors
public void Clear();
// Load a single persisted anchor by name. The ARAnchorManager will create this new anchor and report it in
// the ARAnchorManager.anchorsChanged event. The TrackableId returned here is the same TrackableId the
// ARAnchor will have when it is instantiated.
public TrackableId LoadAnchor(string name);
// Attempts to persist an existing ARAnchor with the given TrackableId to the local store. Returns true if
// the storage is successful, false otherwise.
public bool TryPersistAnchor(TrackableId id, string name);
// Removes a single persisted anchor from the anchor store. This will not affect any ARAnchors in the Unity
// scene, only the anchors in storage.
public void UnpersistAnchor(string name);
}
Obter uma referência de repositório âncora
Para carregar o XRAnchorStore com o Unity 2020 e o OpenXR, use o método de extensão no XRAnchorSubsystem, o subsistema de um ARAnchorManager:
public static Task<XRAnchorStore> LoadAnchorStoreAsync(this XRAnchorSubsystem anchorSubsystem)
Para carregar o XRAnchorStore com o Unity 2019/2020 e o plug-in do Windows XR, use o método de extensão no XRReferencePointSubsystem (Unity 2019) ou XRAnchorSubsystem (Unity 2020), o subsistema de um ARReferencePointManager/ARAnchorManager:
// Unity 2019 + Windows XR Plugin
public static Task<XRAnchorStore> TryGetAnchorStoreAsync(this XRReferencePointSubsystem anchorSubsystem);
// Unity 2020 + Windows XR Plugin
public static Task<XRAnchorStore> TryGetAnchorStoreAsync(this XRAnchorSubsystem anchorSubsystem);
Carregar um repositório âncora
Para carregar um repositório âncora no Unity 2020 e no OpenXR, acesse-o de um subsistema do ARAnchorManager da seguinte maneira:
Para ver um exemplo completo de âncoras persistentes/não persistentes, confira o GameObject de Exemplo de Âncoras –> Âncoras e AnchorsSample.cs script na [Cena de Exemplo de Plug-in OpenXR de Realidade Misturada]((https://github.com/microsoft/OpenXR-Unity-MixedReality-Samples):
Para persistência de holograma em versões mais antigas do Unity ou projetos WSA, use WorldAnchor.
O WorldAnchorStore cria experiências holográficas em que os hologramas permanecem em posições específicas do mundo real em instâncias do aplicativo. Os usuários podem fixar hologramas individuais onde quiserem e encontrá-los posteriormente no mesmo local durante as sessões do aplicativo.
O permite WorldAnchorStore que você mantenha a localização das âncoras mundiais entre as sessões. Para persistir hologramas entre sessões, mantenha um controle separado disso GameObjects usando uma âncora de mundo específica. Você pode criar uma GameObject raiz com uma âncora mundial e ancorar hologramas filho por ela com um deslocamento de posição local.
Para carregar hologramas de sessões anteriores:
Obtenha o WorldAnchorStore.
Carregue os dados do aplicativo âncora mundial, que fornece a ID da âncora mundial.
Carregue a âncora mundial por sua ID.
Para salvar hologramas para sessões futuras:
Obtenha o WorldAnchorStore.
Salve uma âncora mundial, especificando uma ID.
Salve os dados do aplicativo relacionados à âncora mundial junto com o ID.
Obtenha a WorldAnchorStore
Mantenha uma referência ao WorldAnchorStore, para saber quando ele está pronto para executar uma operação. Como essa chamada é assíncrona, assim que o aplicativo for iniciado, você poderá chamar:
WorldAnchorStore.GetAsync(StoreLoaded);
StoreLoadedé o manipulador quando o carregamento termina:WorldAnchorStore
Agora você tem uma referência ao WorldAnchorStore, que pode ser usado para salvar e carregar âncoras mundiais específicas.
Âncora para salvar um mundo
Para salvar uma âncora mundial, nomeie a âncora mundial e passe-a na WorldAnchorStore que você recebeu antes. Se você tentar salvar duas âncoras na mesma cadeia de caracteres, store.Save retornará false. Exclua o salvamento anterior antes de salvar um novo.
private void SaveGame()
{
// Save data about holograms that this world anchor positions
if (!this.savedRoot) // Only save the root once
{
this.savedRoot = this.store.Save("rootGameObject", anchor);
Assert(this.savedRoot);
}
}
Carregar uma âncora mundial
Para carregar uma âncora mundial:
private void LoadGame()
{
// Saved data about holograms that this world anchor positions:
this.savedRoot = this.store.Load("rootGameObject", rootGameObject);
if (!this.savedRoot)
{
// Game root not saved. Re-place objects or start over.
}
}
Você também pode usar store.Delete() para remover uma âncora salva anteriormente e store.Clear() para remover todos os dados salvos anteriormente.
Enumerar âncoras existentes
Para listar âncoras armazenadas, chame GetAllIds.
string[] ids = this.store.GetAllIds();
for (int index = 0; index < ids.Length; index++)
{
Debug.Log(ids[index]);
}
Persistir hologramas para vários dispositivos
Você pode usar as Âncoras Espaciais do Azure para criar uma âncora de nuvem durável de uma âncora do mundo local. Seu aplicativo pode localizar a âncora de nuvem em vários dispositivos HoloLens, iOS e Android, mesmo que os dispositivos não estejam juntos ao mesmo tempo. Como as âncoras de nuvem são persistentes, vários dispositivos podem ver o conteúdo renderizado em relação a essa âncora no mesmo local físico ao longo do tempo.
Próximas etapas
Compartilhar um espaço de coordenadas bloqueado pelo mundo: