Usa las anclas geoespaciales para posicionar contenido real en Unity

Las anclas geoespaciales son un tipo de ancla que te permiten colocar contenido 3D en el mundo real.

Tipos de anclas geoespaciales

Existen tres tipos de anclas geoespaciales, y cada una controla la altitud de manera diferente:

  1. Anclajes WGS84:
    Los anclajes WGS84 permiten colocar contenido 3D en una latitud determinada, longitud y altitud.

  2. Anclas de relieve:
    Las anclas de terreno te permiten colocar contenido utilizando solo la latitud y con una altura relativa al terreno en esa posición. La altitud se determina en relación con el suelo o el piso, según de VPS.

  3. Anclas de techo:
    Las anclas de techo te permiten colocar contenido utilizando solo la latitud y con una altura relativa al techo de un edificio en esa posición. La altitud se determina en relación con la parte superior de un edificio, como se conoce por Streetscape Geometry. De forma predeterminada, se establecerá la altitud del terreno cuando no se coloque en un edificio.

WGS84 Terreno Para techo
Posición horizontal Latitud, longitud Latitud, longitud Latitud, longitud
Posición vertical Relativa a la altitud de WGS84 Relativo al nivel del terreno determinado por Google Maps. En relación con el nivel del techo determinado por Google Maps
¿Necesitas una resolución del servidor? No

Requisitos previos

Asegúrate de habilitar la API de Geospatial antes de continuar.

Cómo colocar las anclas geoespaciales

Cada tipo de ancla tiene APIs dedicadas para crearlos; consulta Tipos de anclas geoespaciales para obtener más información.

Crea un ancla a partir de una prueba de posicionamiento

También puedes crear un ancla geoespacial a partir de un resultado de prueba de resultado. Usa la postura de la prueba de posicionamiento y conviértela en una GeospatialPose. Úsala para colocar cualquiera de los 3 tipos de anclas que se describieron.

Obtén una postura geoespacial a partir de una postura de RA

AREarthManager.Convert(Pose) proporciona una forma adicional de determinar la latitud y longitud convirtiendo una postura de RA en una postura geoespacial.

Obtén una postura de RA a partir de una postura geoespacial

AREarthManager.Convert(GeospatialPose) convierte la posición horizontal, la altitud y la rotación de cuaterniones especificadas por la Tierra con respecto a un marco de coordenadas de este a arriba en una postura de RA con respecto a las coordenadas mundiales de GL.

Elige el método que se adapte a tu caso de uso

Cada método de creación de un ancla tiene compensaciones asociadas que se deben tener en cuenta:

  • Cuando uses la geometría del paisaje urbano, usa una prueba de posicionamiento para adjuntar contenido a un edificio.
  • Se recomienda usar las anclas de terreno o techo en lugar de las de WGS84, ya que usan valores de altitud determinados por Google Maps.

Determina la latitud y longitud de una ubicación

Hay tres formas de calcular la latitud y longitud de una ubicación:

  • Usa el Creador de Geospatial para ver y aumentar el mundo con contenido en 3D sin tener que ir físicamente a una ubicación. Esto te permite colocar contenido envolvente en 3D de forma visual con mapas de Google Maps en Unity Editor. La latitud, la longitud, la rotación y la altitud del contenido se calcularán automáticamente.
  • Usar Google Maps
  • Usa Google Earth. Ten en cuenta que si obtienes estas coordenadas con Google Earth, en lugar de hacerlo con Google Maps, obtendrás un margen de error de hasta varios metros.
  • Ve a la ubicación física

Usar Google Maps

Para obtener la latitud y longitud de una ubicación con Google Maps, sigue estos pasos:

  1. Ve a Google Maps en tu computadora de escritorio.

  2. Navega a Capas > Más.

  3. Cambia el campo Tipo de mapa a Satélite y desmarca la casilla de verificación Vista en el globo terráqueo en la esquina inferior izquierda de la pantalla.

    Esto forzará una perspectiva en 2D y eliminará posibles errores que podrían surgir de una vista 3D angular.

  4. En el mapa, haz clic con el botón derecho en la ubicación y selecciona la longitud o latitud para copiarla en el portapapeles.

Cómo usar Google Earth

Para calcular la latitud y longitud de una ubicación desde Google Earth, haz clic en una ubicación en la interfaz de usuario y lee los datos de los detalles del marcador.

Para obtener la latitud y longitud de una ubicación con Google Earth, sigue estos pasos:

  1. Ve a Google Earth en la computadora de escritorio.

  2. Navega hasta el menú de hamburguesa y selecciona Estilo del mapa.

  3. Desactiva el interruptor de Edificios 3D.

  4. Después de desactivar el interruptor Edificios 3D, haz clic en el ícono de fijar para agregar un marcador en la ubicación seleccionada.

  5. Especifica un proyecto que contenga el marcador y haz clic en Guardar.

  6. En el campo Título del marcador, ingresa su nombre.

  7. Haz clic en la flecha hacia atrás en el panel del proyecto y selecciona el menú Más acciones.

  8. Elige Exportar como archivo KML en el menú.

El archivo KLM informa la latitud, la longitud y la altitud de un marcador de la etiqueta <coordinates>, separados por comas, de la siguiente manera:

<coordinates>-122.0755182435043,37.41347299422944,7.420342565583832</coordinates>

No uses la latitud y longitud de las etiquetas <LookAt>, que especifican la posición de la cámara, no la ubicación.

Ve a la ubicación física

Para calcular la altitud de una ubicación, ve a esa ubicación física y realiza una observación local.

Obtén el cuaternión de rotación

GeospatialPose.EunRotation extrae la orientación de una posición geoespacial y genera un cuaternión que representa la matriz de rotación que transforma un vector del objetivo al sistema de coordenadas este-arriba (EUN). X+ apunta al este, Y+ apunta hacia arriba en dirección opuesta a la gravedad y Z+ apunta al norte.

Anclas WGS84

Un ancla WGS84 es un tipo de ancla que te permite colocar contenido en 3D en cualquier latitud, longitud y altitud. Se basa en una postura y en la orientación para colocarse en el mundo real. La posición consta de los campos de latitud, longitud y altitud que se especifican en el sistema de coordenadas WGS84. La orientación consiste en una rotación de cuaternión.

La altitud se informa en metros por encima del elipsoide WGS84 de referencia, de modo que el nivel del suelo no sea cero. Tu app es responsable de proporcionar estas coordenadas para cada ancla creada.

Coloca un ancla WGS84 en el mundo real

Cómo determinar la altitud de una ubicación

Existen varias formas de determinar la altitud de una ubicación para colocar las anclas:

  • Si la ubicación del ancla se encuentra físicamente cerca del usuario, puedes utilizar una altitud similar a la del dispositivo del usuario.
  • Una vez que tengas la latitud y la longitud, usa la API de Elevation para obtener una elevación según la especificación EGM96. Debes convertir la elevación de EGM96 de la API de Google Maps a WGS84 para compararla con la altitud de GeospatialPose. Consulta el archivo GeoidEval que tiene una línea de comandos y una interfaz HTML. La API de Google Maps informa las coordenadas de latitud y longitud según la especificación WGS84.
  • Puedes consultar la latitud, la longitud y la altitud de una ubicación en Google Earth. Aparecerá un margen de error de hasta varios metros. Utiliza la latitud, la longitud y la altitud de las etiquetas <coordinates>, no las etiquetas <LookAt>, en el archivo KML.
  • Si un ancla existente está cerca y si no tienes una inclinación empinada, podrás utilizar la altitud del parámetro GeospatialPose de la cámara sin utilizar otra fuente, como la API de Google Maps.

Crea el ancla

Una vez que tengas la latitud, la longitud, la altitud y el cuaternión de rotación, usa ARAnchorManagerExtensions.AddAnchor() para anclar el contenido a las coordenadas geográficas que especifiques.

if (earthTrackingState == TrackingState.Tracking)
{
  var anchor =
      AnchorManager.AddAnchor(
          latitude,
          longitude,
          altitude,
          quaternion);
  var anchoredAsset = Instantiate(GeospatialAssetPrefab, anchor.transform);
}

Anclas para terreno

Un ancla de terreno es un tipo de ancla que te permite colocar objetos de RA solo con la latitud y la longitud, y aprovechando la información del VPS para determinar la altitud precisa sobre el suelo.

En lugar de ingresar la altitud deseada, proporcionas la altitud sobre el terreno. Cuando el valor sea cero, el ancla estará nivelada con el terreno.

Configura el modo de búsqueda de aviones

La búsqueda de planos es opcional y no es obligatorio para usar anclas. Ten en cuenta que solo se usan planos horizontales. Los planos horizontales facilitan la alineación dinámica de los anclajes de terreno en el suelo.

Ten en cuenta que los anclajes de terreno se ven afectados por Horizontal y Horizontal | Vertical

Utiliza el menú desplegable Modo de detección para configurar el modo de detección:

Cómo crear un ancla de terreno con la nueva API de Async

Para crear y colocar un ancla de relieve, llama a ARAnchorManagerExtensions.resolveAnchorOnTerrainAsync().

El ancla no estará lista de inmediato y debe resolverse. Una vez que se resuelva, estará disponible en el ResolveAnchorOnTerrainPromise.

public GameObject TerrainAnchorPrefab;

public void Update()
{
    ResolveAnchorOnTerrainPromise terrainPromise =
        AnchorManager.ResolveAnchorOnTerrainAsync(
            latitude, longitude, altitudeAboveTerrain, eunRotation);

    // The anchor will need to be resolved.
    StartCoroutine(CheckTerrainPromise(terrainPromise));
}

private IEnumerator CheckTerrainPromise(ResolveAnchorOnTerrainPromise promise)
{
    yield return promise;

    var result = promise.Result;
    if (result.TerrainAnchorState == TerrainAnchorState.Success &&
        result.Anchor != null)
    {
        // resolving anchor succeeded
        GameObject anchorGO = Instantiate(TerrainAnchorPrefab,
            result.Anchor.gameObject.transform);
        anchorGO.transform.parent = result.Anchor.gameObject.transform;
    }
    else
    {
       // resolving anchor failed
    }

    yield break;
}

Comprueba el estado de la promesa

La promesa tendrá un PromiseState asociado.

Estado Descripción
Pending La operación aún está pendiente.
Done Se completó la operación y el resultado está disponible.
Cancelled Se canceló la operación.

Verifica el estado del ancla del terreno del resultado de la promesa

El TerrainAnchorState pertenece a la operación asíncrona y es parte del resultado final de la promesa.

switch (result.TerrainAnchorState)
{
    case TerrainAnchorState.Success:
        // Anchor has successfully resolved
        break;
    case TerrainAnchorState.ErrorUnsupportedLocation:
        // The requested anchor is in a location that isn't supported by the Geospatial API.
        break;
    case TerrainAnchorState.ErrorNotAuthorized:
        // An error occurred while authorizing your app with the ARCore API. See
        // https://developers.google.com/ar/reference/unity-arf/namespace/Google/XR/ARCoreExtensions#terrainanchorstate_errornotauthorized
        // for troubleshooting steps.
        break;
    case TerrainAnchorState.ErrorInternal:
        // The Terrain anchor could not be resolved due to an internal error.
        break;
    default:
        break;
}

Anclajes para techos

Hero image de anclas de techo

Las anclas de techo son un tipo de ancla y son muy similares a las anclas de relieve mencionadas anteriormente. La diferencia es que proporcionarás la altitud sobre el techo en lugar de la altitud sobre el terreno.

Cómo crear un ancla de techo con la nueva API de Async

El ancla no estará lista de inmediato y debe resolverse.

Para crear y colocar un ancla de techo, llama a ARAnchorManagerExtensions.resolveAnchorOnRooftopAsync(). Al igual que con las anclas de terreno, también accederás al elemento PromiseState de la promesa. Luego, puedes verificar el resultado de la promesa para acceder a RooftopAnchorState.

public GameObject RooftopAnchorPrefab;

public void Update()
{
    ResolveAnchorOnRooftopPromise rooftopPromise =
        AnchorManager.ResolveAnchorOnRooftopAsync(
            latitude, longitude, altitudeAboveRooftop, eunRotation);

    // The anchor will need to be resolved.
    StartCoroutine(CheckRooftopPromise(rooftopPromise));
}

private IEnumerator CheckRooftopPromise(ResolveAnchorOnTerrainPromise promise)
{
    yield return promise;

    var result = promise.Result;
    if (result.RooftopAnchorState == RooftopAnchorState.Success &&
        result.Anchor != null)
    {
        // resolving anchor succeeded
        GameObject anchorGO = Instantiate(RooftopAnchorPrefab,
            result.Anchor.gameObject.transform);
        anchorGO.transform.parent = result.Anchor.gameObject.transform;
    }
    else
    {
       // resolving anchor failed
    }

    yield break;
}

Comprueba el estado de la promesa

La promesa tendrá un PromiseState asociado. Consulta la tabla anterior.

Verifica el estado de ancla de techo del resultado de la promesa

El RooftopAnchorState pertenece a la operación asíncrona y es parte del resultado final de la promesa.

switch (result.RooftopAnchorState)
{
    case TerrainAnchorState.Success:
        // Anchor has successfully resolved
        break;
    case RooftopAnchorState.ErrorUnsupportedLocation:
        // The requested anchor is in a location that isn't supported by the Geospatial API.
        break;
    case RooftopAnchorState.ErrorNotAuthorized:
        // An error occurred while authorizing your app with the ARCore API. See
        // https://developers.google.com/ar/reference/unity-arf/namespace/Google/XR/ARCoreExtensions#terrainanchorstate_errornotauthorized
        // for troubleshooting steps.
        break;
    case RooftopAnchorState.ErrorInternal:
        // The Rooftop anchor could not be resolved due to an internal error.
        break;
    default:
        break;
}

¿Qué sigue?