Coordenar sistemas no Unity

Windows Mixed Reality suporta aplicações numa vasta gama de escalas de experiência, desde aplicações apenas de orientação e de escalamento sentado até aplicações à escala de salas. No HoloLens, pode ir mais longe e criar aplicações à escala mundial que permitem aos utilizadores percorrer mais de 5 metros, explorando um piso inteiro de um edifício e mais além.

O primeiro passo na criação de uma experiência de realidade mista no Unity é compreender os sistemas de coordenadas e escolher a experiência de dimensionamento da sua aplicação.

Criar uma experiência só de orientação ou em escala sentada

Espaço de nomes:UnityEngine.XR
Tipo:XRDevice

Para criar uma experiência apenas de orientação ou de escalamento sentado, tem de definir o Unity para o tipo de espaço de controlo Estacionário. O espaço de controlo estacionário define o sistema de coordenadas mundiais do Unity para controlar o quadro estacionário de referência. No modo de controlo Estacionário, o conteúdo colocado no editor imediatamente em frente à localização predefinida da câmara (reencaminhar é -Z) será apresentado à frente do utilizador quando a aplicação for iniciada.

XRDevice.SetTrackingSpaceType(TrackingSpaceType.Stationary);

Espaço de nomes:UnityEngine.XR
Type:InputTracking

Para uma experiência apenas de orientação pura, como um visualizador de vídeo de 360 graus (onde as atualizações posicionais da cabeça arruinariam a ilusão), pode definir XR. InputTracking.disablePositionalTracking como verdadeiro:

InputTracking.disablePositionalTracking = true;

Para uma experiência à escala de assentos, para permitir que o utilizador mais tarde recenteize a origem sentada, pode chamar o XR. Método InputTracking.Recenter :

InputTracking.Recenter();

Criar uma experiência em escala permanente ou à escala de salas

Espaço de nomes:UnityEngine.XR
Tipo:XRDevice

Para uma experiência em escala permanente ou à escala de salas, terá de colocar conteúdo em relação ao piso. O utilizador deve utilizar a fase espacial, que representa a origem definida ao nível do piso do utilizador e o limite opcional da sala, configurado durante a primeira execução.

Para garantir que o Unity está a funcionar com o respetivo sistema de coordenadas mundiais ao nível do piso, pode definir e testar que o Unity está a utilizar o tipo de espaço de controlo 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 devolver verdadeiro, o Unity alterou com êxito o sistema de coordenadas do mundo para controlar o quadro de referência da fase.
  • Se SetTrackingSpaceType devolver falso, o Unity não conseguiu mudar para o quadro de referência de fase, provavelmente porque o utilizador não configurou um piso no respetivo ambiente. Embora um valor devolvido falso não seja comum, pode acontecer se a fase estiver configurada numa sala diferente e o dispositivo for movido para a sala atual sem que o utilizador configure uma nova fase.

Assim que a sua aplicação definir com êxito o tipo de espaço de controlo RoomScale, o conteúdo colocado no plano y=0 será apresentado no chão. A origem em 0, 0, 0 será o local específico no piso onde o utilizador ficou durante a configuração da sala, com -Z representando a direção para a frente que estavam virados durante a configuração.

Espaço de nomes:UnityEngine.Experimental.XR
Tipo:Limite

No código do script, pode chamar o método TryGetGeometry no tipo UnityEngine.Experimental.XR.Boundary para obter um polígono de limite, especificando um tipo de limite de TrackedArea. Se o utilizador definiu um limite (obtém de volta uma lista de vértices), é seguro proporcionar uma experiência à escala de salas ao utilizador, onde pode percorrer a cena que criar.

Nota

O sistema irá compor automaticamente o limite quando o utilizador se aproximar do mesmo. A sua aplicação não precisa de utilizar este polígono para compor o próprio limite. No entanto, pode optar por esquematizar os objetos de cena com este polígono de limite, para garantir que o utilizador consegue alcançar fisicamente esses objetos sem teletransportar:

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.
}

Criar uma experiência à escala mundial

Espaço de nomes:UnityEngine.XR.WSA
Tipo:WorldAnchor

Para experiências verdadeiras à escala mundial no HoloLens que permitem aos utilizadores vaguear por mais de 5 metros, precisará de novas técnicas para além das utilizadas para experiências à escala de salas. Uma das principais técnicas que irá utilizar é criar uma âncora espacial para bloquear um cluster de hologramas precisamente no mundo físico, independentemente do quão longe o utilizador tenha percorrido e, em seguida, encontrar esses hologramas novamente em sessões posteriores.

No Unity, cria uma âncora espacial ao adicionar o componente WorldAnchor Unity a um GameObject.

Adicionar uma Âncora Mundial

Para adicionar uma âncora mundial, chame AddComponent<WorldAnchor>() no objeto de jogo com a transformação que pretende ancorar no mundo real.

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

Já está! Este objeto de jogo será agora ancorado à sua localização atual no mundo físico - poderá ver as coordenadas do mundo do Unity ajustarem-se ligeiramente ao longo do tempo para garantir esse alinhamento físico. Utilize a persistência para encontrar esta localização ancorada novamente numa futura sessão de aplicação.

Remover uma Âncora Mundial

Se já não pretender que o GameObject esteja bloqueado numa localização física do mundo e não pretenda movê-lo, pode simplesmente chamar Destruir no componente World Anchor.

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

Se quiser mover o GameObject para esta moldura, tem de chamar DestroyImmediate como alternativa.

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

Moving a World Anchored GameObject

O GameObject não pode ser movido enquanto um World Anchor estiver nele. Se precisar de mover o GameObject para esta moldura, tem de:

  1. DestroyImmediate the World Anchor component (DestruirImmediar o componente World Anchor)
  2. Mover o GameObject
  3. Adicione um novo componente World Anchor ao GameObject.
DestroyImmediate(gameObject.GetComponent<WorldAnchor>());
gameObject.transform.position = new Vector3(0, 0, 2);
WorldAnchor anchor = gameObject.AddComponent<WorldAnchor>();

Processar Alterações de Localizabilidade

Um WorldAnchor pode não ser localizado no mundo físico num momento. Se isso ocorrer, o Unity não atualizará a transformação do objeto ancorado. Isto também pode ser alterado enquanto uma aplicação está em execução. A falha ao lidar com a alteração na localizabilidade fará com que o objeto não apareça na localização física correta no mundo.

Para ser notificado sobre as alterações de localizabilidade:

  1. Subscrever o evento OnTrackingChanged
  2. Processar o evento

O evento OnTrackingChanged será chamado sempre que a âncora espacial subjacente for alterada entre um estado de localização vs. não ser localizável.

anchor.OnTrackingChanged += Anchor_OnTrackingChanged;

Em seguida, processe o 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);
}

Por vezes, as âncoras são localizadas imediatamente. Neste caso, esta propriedade isLocated da âncora será definida como verdadeira quando AddComponent<WorldAnchor>() devolver. Como resultado, o evento OnTrackingChanged não será acionado. Um padrão limpo seria chamar o processador OnTrackingChanged com o estado isLocated inicial depois de anexar uma âncora.

Anchor_OnTrackingChanged(anchor, anchor.isLocated);

Partilhar âncoras entre dispositivos

Utilize o Azure Spatial Anchors para criar uma âncora de cloud durável a partir de um WorldAnchor local, que a sua aplicação pode localizar em vários dispositivos HoloLens, iOS e Android. Ao partilhar uma âncora espacial comum em vários dispositivos, cada utilizador pode ver conteúdo composto em relação a essa âncora na mesma localização física. Isto permite experiências partilhadas em tempo real.

Para começar a criar experiências partilhadas no Unity, experimente os inícios rápidos do Unity do Azure Spatial Anchors de 5 minutos.

Assim que estiver a trabalhar com o Azure Spatial Anchors, pode criar e localizar âncoras no Unity.

Próximo Ponto de Verificação de Desenvolvimento

Se estiver a seguir o percurso de ponto de verificação de desenvolvimento do Unity que definimos, está no meio de explorar os blocos modulares Mixed Reality principais. A partir daqui, pode continuar para o bloco modular seguinte:

Em alternativa, avance para Mixed Reality capacidades e APIs da plataforma:

Pode sempre voltar aos pontos de verificação de desenvolvimento do Unity em qualquer altura.

Consulte também