Sistemas de coordenadas de Unity

Windows Mixed Reality admite aplicaciones en una amplia gama de escalas de experiencia, desde aplicaciones de solo orientación y de escalado vertical a través de aplicaciones a escala de sala. En HoloLens, puede ir más allá y crear aplicaciones a escala mundial que permitan a los usuarios caminar más allá de 5 metros, explorar un piso completo de un edificio y más allá.

El primer paso para crear una experiencia de realidad mixta en Unity es comprender los sistemas de coordenadas y elegir la escala de la experiencia que tendrá como destino la aplicación.

Creación de una experiencia de solo orientación o de escalado sentado

Espacio de nombres:UnityEngine.XR
Type:XRDevice

Para crear una experiencia de solo orientación o de escalado sentado, debe establecer Unity en el tipo de espacio de seguimiento estacionario. El espacio de seguimiento estacionario establece el sistema de coordenadas del mundo de Unity para realizar un seguimiento del marco de referencia estacionario. En el modo de seguimiento estacionario, el contenido colocado en el editor justo delante de la ubicación predeterminada de la cámara (forward es -Z) aparecerá delante del usuario cuando se inicie la aplicación.

XRDevice.SetTrackingSpaceType(TrackingSpaceType.Stationary);

Espacio de nombres:UnityEngine.XR
Type:InputTracking

Para una experiencia de solo orientación pura, como un visor de vídeo de 360 grados (donde las actualizaciones de cabeza posicional arruinarían la ilusión), puede establecer XR. InputTracking.disablePositionalTracking en true:

InputTracking.disablePositionalTracking = true;

Para obtener una experiencia de escalado sentado, para permitir que el usuario más adelante haga más reciente el origen sentado, puede llamar a la XR. Método InputTracking.Recenter :

InputTracking.Recenter();

Creación de una experiencia a escala permanente o a escala de salas

Espacio de nombres:UnityEngine.XR
Type:XRDevice

Para una experiencia de escala permanente o de escala de sala, deberá colocar contenido en relación con el piso. El motivo es que el piso del usuario use la fase espacial, que representa el origen de nivel de piso definido por el usuario y el límite de la sala opcional, configurado durante la primera ejecución.

Para asegurarse de que Unity funciona con su sistema de coordenadas del mundo en el nivel de planta, puede establecer y probar que Unity usa el tipo de espacio de seguimiento 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.
}
  • Si SetTrackingSpaceType devuelve true, Unity ha cambiado correctamente su sistema de coordenadas del mundo para realizar un seguimiento del marco de la fase de referencia.
  • Si SetTrackingSpaceType devuelve false, Unity no pudo cambiar al marco de referencia de fase, probablemente porque el usuario no ha configurado un piso en su entorno. Aunque un valor devuelto falso no es común, puede ocurrir si la fase está configurada en otra sala y el dispositivo se mueve a la sala actual sin que el usuario configure una nueva fase.

Una vez que la aplicación establece correctamente el tipo de espacio de seguimiento RoomScale, el contenido colocado en el plano y=0 aparecerá en el suelo. El origen en 0, 0, 0 será el lugar específico en el piso donde el usuario estaba durante la instalación de la sala, con -Z que representa la dirección hacia delante que estaban orientadas durante la instalación.

Espacio de nombres:UnityEngine.Experimental.XR
Type:Boundary

En el código de script, puede llamar al método TryGetGeometry en el tipo UnityEngine.Experimental.XR.Boundary para obtener un polígono de límite, especificando un tipo de límite de TrackedArea. Si el usuario definió un límite (se devuelve una lista de vértices), es seguro ofrecer una experiencia de escala de sala al usuario, donde puede recorrer la escena que cree.

Nota:

El sistema representará automáticamente el límite cuando el usuario se acerque a él. La aplicación no necesita usar este polígono para representar el propio límite. Sin embargo, puede optar por diseñar los objetos de escena mediante este polígono de límites, para asegurarse de que el usuario pueda llegar físicamente a esos objetos sin 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.
}

Creación de una experiencia a escala mundial

Espacio de nombres:UnityEngine.XR.WSA
Type:WorldAnchor

En el caso de experiencias verdaderas a escala mundial en HoloLens que permiten a los usuarios recorrer más de 5 metros, necesitará nuevas técnicas más allá de las usadas para las experiencias a escala de espacio. Una técnica clave que usará es crear un delimitador espacial para bloquear un clúster de hologramas exactamente en el mundo físico, independientemente de la distancia que el usuario haya desplazado y, a continuación, buscar esos hologramas de nuevo en sesiones posteriores.

En Unity, se crea un delimitador espacial agregando el componente De Unity WorldAnchor a gameObject.

Agregar un delimitador mundial

Para agregar un delimitador del mundo, llama a AddComponent<WorldAnchor>() en el objeto del juego con la transformación que quieres delimitar en el mundo real.

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

Eso es todo. Este objeto de juego se anclará ahora a su ubicación actual en el mundo físico; es posible que vea que sus coordenadas del mundo de Unity se ajustan ligeramente con el tiempo para asegurarse de que la alineación física. Use la persistencia para volver a buscar esta ubicación anclada en una sesión futura de la aplicación.

Quitar un delimitador mundial

Si ya no quieres que gameObject esté bloqueado en una ubicación física del mundo y no quiera moverlo, puedes llamar a Destroy en el componente World Anchor.

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

Si quieres mover el objeto GameObject, debes llamar a DestroyImmediate en su lugar.

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

Mover un GameObject delimitado mundial

GameObject no se puede mover mientras un Delimitador mundial está en él. Si necesitas mover el objeto GameObject este fotograma, debes:

  1. DestroyImmediate el componente World Anchor
  2. Mover gameObject
  3. Agregue un nuevo componente World Anchor al GameObject.
DestroyImmediate(gameObject.GetComponent<WorldAnchor>());
gameObject.transform.position = new Vector3(0, 0, 2);
WorldAnchor anchor = gameObject.AddComponent<WorldAnchor>();

Control de cambios de portabilidad

Un WorldAnchor puede no ser locable en el mundo físico en un momento dado. Si esto ocurre, Unity no actualizará la transformación del objeto delimitado. Esto también puede cambiar mientras se ejecuta una aplicación. Si no se controla el cambio en la localización, el objeto no aparecerá en la ubicación física correcta del mundo.

Para recibir una notificación sobre los cambios de portabilidad:

  1. Suscribirse al evento OnTrackingChanged
  2. Controlar el evento

Se llamará al evento OnTrackingChanged cada vez que el delimitador espacial subyacente cambie entre un estado de locable frente a no ser locable.

anchor.OnTrackingChanged += Anchor_OnTrackingChanged;

A continuación, controle el 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);
}

A veces, los anclajes se encuentran inmediatamente. En este caso, esta propiedad isLocated del delimitador se establecerá en true cuando AddComponent<WorldAnchor>() devuelva. Como resultado, el evento OnTrackingChanged no se desencadenará. Un patrón limpio sería llamar al controlador OnTrackingChanged con el estado IsLocated inicial después de adjuntar un delimitador.

Anchor_OnTrackingChanged(anchor, anchor.isLocated);

Uso compartido de anclajes entre dispositivos

Use Azure Spatial Anchors para crear un delimitador de nube duradero desde un WorldAnchor local, que la aplicación puede localizar en varios dispositivos HoloLens, iOS y Android. Al compartir un delimitador espacial común en varios dispositivos, cada usuario puede ver el contenido representado en relación con ese delimitador en la misma ubicación física. Esto permite compartir experiencias en tiempo real.

Para empezar a crear experiencias compartidas en Unity, pruebe los inicios rápidos de Azure Spatial Anchors Unity de 5 minutos.

Una vez que esté en funcionamiento con Azure Spatial Anchors, puede crear y buscar anclajes en Unity.

Siguiente punto de control de desarrollo

Si sigue el recorrido del punto de comprobación de desarrollo de Unity que hemos diseñado, está en medio de explorar los bloques de creación principales de Mixed Reality. Desde aquí, puede continuar con el siguiente bloque de compilación:

O bien puede saltar a las funcionalidades y las API de la plataforma de realidad mixta:

Puede volver a los puntos de control de desarrollo de Unity en cualquier momento.

Consulte también