Używaj kotwic geoprzestrzennych, aby umieszczać rzeczywiste treści w Unity

Kotwy geoprzestrzenne to rodzaj kotwic, które umożliwiają umieszczanie treści 3D w rzeczywistym świecie.

Typy punktów odniesienia geoprzestrzennych

Istnieją 3 rodzaje punktów odniesienia geoprzestrzennego, które inaczej obsługują wysokość:

  1. Punkty kotwiczenia WGS84:
    Punkty kotwiczenia WGS84 umożliwiają umieszczanie treści 3D w dowolnej szerokości geograficznej, długości geograficznej i wysokości.

  2. Punkty kotwiczenia w terenie:
    Punkty kotwiczenia w terenie umożliwiają umieszczanie treści tylko za pomocą współrzędnych szerokości i długości geograficznej oraz wysokości w stosunku do terenu w danej pozycji. Wysokość jest określana względem podłoża lub podłogi, jaką zna VPS.

  3. Punkty kotwiczenia na dachu:
    Punkty kotwiczenia na dachu umożliwiają umieszczanie treści tylko za pomocą współrzędnych geograficznych (szerokość i długość geograficzna) z wysokość względną w stosunku do dachu budynku w danej pozycji. Wysokość jest określana względem szczytu budynku zgodnie z danymi Streetscape Geometry. Domyślnie jest to wysokość terenu, jeśli obiekt nie znajduje się na budynku.

WGS84 Teren Dach
Pozycja w poziomie Szerokość geograficzna, długość geograficzna Szerokość geograficzna, długość geograficzna Szerokość geograficzna, długość geograficzna
Pozycja pionowa Względem wysokości WGS84 Względem poziomu terenu określonego przez Mapy Google Względem poziomu dachu określonego przez Mapy Google
Czy problem musi zostać rozwiązany na serwerze? Nie Tak Tak

Wymagania wstępne

Zanim przejdziesz dalej, włącz interfejs Geospatial API.

Umieszczenie kotwic geoprzestrzennych

Każdy typ kotwicy ma dedykowane interfejsy API do ich tworzenia. Więcej informacji znajdziesz w artykule Typy kotwic geoprzestrzennych.

Tworzenie kotwicy na podstawie testu trafień

Możesz też utworzyć punkt odniesienia geoprzestrzennego na podstawie wyników testu trafień. Użyj pozy z testu kolizji i przekształć ją w GeospatialPose. Używaj go do umieszczania dowolnego z 3 opisanych typów kotwic.

Pobieranie danych geoprzestrzennych z pozy AR

AREarthManager.Convert(Pose) zapewnia dodatkowy sposób określania szerokości i długości geograficznej przez konwersję pozy AR na pozę geoprzestrzenną.

Pobieranie pozy AR z pozy geoprzestrzennej

AREarthManager.Convert(GeospatialPose) konwertuje pozycję poziomą, wysokość i obrot kwaterniony zdefiniowane przez Ziemię w układzie współrzędnych wschód-góra-południe na pozę AR zdefiniowaną w układzie współrzędnych świata GL.

Wybierz metodę odpowiednią do Twojego przypadku użycia

Każda metoda tworzenia kotwicy ma związane z nią kompromisy, o których warto pamiętać:

  • Jeśli używasz geometrii Streetscape, dołącz treści do budynku za pomocą testu kolizji.
  • Zamiast punktów kotwiczenia WGS84 używaj punktów kotwiczenia Teren lub Dach, ponieważ wykorzystują one wartości wysokości określone przez Mapy Google.

Określanie szerokości i długości geograficznej lokalizacji

Szerokość i długość geograficzną lokalizacji można obliczyć na 3 sposoby:

  • Korzystaj z narzędzia Geospatial Creator, aby wyświetlać i rozszerzać świat o treści 3D bez konieczności fizycznego przemieszczania się do danej lokalizacji. Pozwala to wizualnie umieszczać w mapach Google w Edytorze Unity treści w 3D. Szerokość, długość geograficzna, obrót i wysokość treści zostaną automatycznie obliczone.
  • Użyj Map Google
  • Użyj Google Earth. Pamiętaj, że uzyskanie tych współrzędnych za pomocą Google Earth, a nie Map Google, spowoduje powstanie marginesu błędu wynoszącego do kilku metrów.
  • Przejdź do fizycznej lokalizacji

Użyj Map Google

Aby uzyskać współrzędne geograficzne lokalizacji w Mapach Google:

  1. Na komputerze otwórz Mapy Google.

  2. Kliknij Warstwy > Więcej.

  3. Zmień Typ mapy na Satelita i odznacz pole wyboru Widok kuli ziemskiej w lewym dolnym rogu ekranu.

    Spowoduje to wymuszenie perspektywy 2D i wyeliminuje ewentualne błędy, które mogłyby wystąpić w przypadku widoku 3D pod kątem.

  4. Na mapie kliknij lokalizację prawym przyciskiem myszy i wybierz długość/szerokość geograficzną, aby skopiować te dane do schowka.

Korzystanie z Google Earth

Możesz obliczyć szerokość i długość geograficzną lokalizacji w Google Earth, klikając lokalizację w interfejsie i odczytując dane z szczegółów oznaczenia miejsca.

Aby uzyskać szerokość i długość geograficzną lokalizacji w Google Earth:

  1. Otwórz Google Earth na komputerze stacjonarnym.

  2. Kliknij menu hamburgera  i wybierz Styl mapy.

  3. Wyłącz przełącznik Budynki 3D.

  4. Gdy przełącznik Budynki 3D jest wyłączony, kliknij ikonę szpilki , aby dodać znacznik miejsca w wybranej lokalizacji.

  5. Określ projekt, który ma zawierać oznaczenie miejsca, i kliknij Zapisz.

  6. W polu Tytuł oznaczenia miejsca wpisz nazwę oznaczenia.

  7. W panelu projektu kliknij strzałkę wstecz  i wybierz menu  Więcej działań.

  8. W menu kliknij Eksportuj jako plik KML.

Plik KLM zawiera szerokość, długość geograficzną i wysokość miejsca w tagu <coordinates> rozdzielone przecinkami w ten sposób:

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

Nie używaj szerokości i długości geograficznej z tagów <LookAt>, które określają położenie kamery, a nie lokalizację.

Przejdź do fizycznej lokalizacji

Możesz obliczyć wysokość lokalizacji, udając się tam osobiście i wykonując obserwację lokalną.

Pobieranie kwaternonu obrotu

GeospatialPose.EunRotation wyodrębnia orientację z postaci geometrycznej i wyprowadza kwadrokty, który reprezentuje macierz obrotu przekształcającą wektor z docelowego układu współrzędnych wschód-góra-północ (EUN). X+ wskazuje na wschód, Y+ na górę, a Z+ na północ.

Punkty zakotwiczenia WGS84

Punkt zakotwiczenia WGS84 to rodzaj punktu kotwiczenia, który umożliwia umieszczanie treści 3D w dowolnej szerokości, długości geograficznej i wysokości. Używa ona pozycji i orientacji, aby umieścić obiekt w świecie rzeczywistym. Pozycja składa się z szerokości, długości i wysokości geograficznej, które są określone w systemie współrzędnych WGS84. Orientacja składa się z obrotu kwateranionowego.

Wysokość jest podawana w metrach nad elipsoidą odniesienia WGS84, dzięki czemu poziom gruntu nie wynosi zero. Twoja aplikacja jest odpowiedzialna za podanie tych współrzędnych w przypadku każdego utworzonego kotwicy.

Umieszczenie punktu odniesienia WGS84 w świecie rzeczywistym

Określanie wysokości lokalizacji

Istnieje kilka sposobów na określenie wysokości lokalizacji na potrzeby umieszczania kotwic:

  • Jeśli lokalizacja kotwicy znajduje się fizycznie blisko użytkownika, możesz użyć wysokości podobnej do wysokości urządzenia użytkownika.
  • Gdy już masz współrzędne geograficzne, użyj interfejsu Elevation API, aby uzyskać wysokość na podstawie specyfikacji EGM96. Aby porównać wysokość wg EGM96 z interfejsem API Mapy, musisz przekonwertować wysokość wg EGM96 na WGS84.GeospatialPose Zapoznaj się z narzędziem GeoidEval, które ma zarówno interfejs wiersza poleceń, jak i interfejs HTML. Interfejs Maps API podaje szerokość i długość geograficzną zgodnie ze specyfikacją WGS84.
  • Szerokość geograficzną, długość geograficzną i wysokość lokalizacji możesz uzyskać w Google Earth. To da Ci margines błędu do kilku metrów. W pliku KML używaj współrzędnych geograficznych i wysokości z tagów <coordinates>, a nie tagów <LookAt>.
  • Jeśli istniejąca kotwica jest blisko i nie znajdujesz się na stromym zboczu, możesz użyć wysokości z GeospatialPose aparatu bez korzystania z innego źródła, takiego jak interfejs Maps API.

Tworzenie kotwicy

Gdy masz już szerokość geograficzną, długość geograficzną, wysokość i kwaternion obrotu, użyj elementu ARAnchorManagerExtensions.AddAnchor(), aby zakotwiczyć treści w określonych przez siebie współrzędnych geograficznych.

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

Kotwicy terenu

Kotwica terenu to rodzaj kotwicy, która umożliwia umieszczanie obiektów AR tylko na podstawie szerokości i długości geograficznej. Korzysta ona z informacji z VPS, aby określić dokładną wysokość nad poziomem morza.

Zamiast podawać żądaną wysokość, podajesz wysokość nad rzeźbą terenu. Jeśli jest ona równa zeru, kotwica będzie na poziomie terenu.

Ustawianie trybu wyszukiwania samolotu

Wyszukiwanie samolotów jest opcjonalne i nie jest wymagane do korzystania z kotwic. Pamiętaj, że używane są tylko płaszczyzny poziome. Płaszczyzny poziome pomogą w dynamicznym dopasowywaniu punktów kotwiczenia terenu do podłoża.

Pamiętaj, że na kotwy terenu wpływają parametry HorizontalHorizontal | Vertical.

Aby ustawić tryb wykrywania, użyj menu Tryb wykrywania:

Tworzenie punktu kotwiczenia terenu za pomocą nowego interfejsu Async API

Aby utworzyć i umieścić punkt odniesienia terenu, wybierz ARAnchorManagerExtensions.resolveAnchorOnTerrainAsync().

Kotwica nie będzie gotowa od razu i musi się rozwiązać. Gdy problem zostanie rozwiązany, będzie dostępny w sekcji 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;
}

Sprawdzanie stanu zobowiązania

Obietnica będzie powiązana z PromiseState.

Stan Opis
Pending Operacja jest nadal w toku.
Done Operacja została zakończona, a jej wynik jest dostępny.
Cancelled Operacja została anulowana.

Sprawdzanie stanu kotwicy terenu w wyniku obietnicy

Wartość TerrainAnchorState należy do operacji asynchronicznej i jest częścią końcowego wyniku obietnicy.

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

Kotwy dachowe

Elementy główne dotyczące kotew dachowych

Punkty kotwiczenia na dachu to rodzaj punktu kotwiczenia i są bardzo podobne do punktów kotwiczenia na terenie. Różnica polega na tym, że podasz wysokość nad dachem, a nie nad terenem.

Tworzenie kotwicy Rooftop za pomocą nowego interfejsu Async API

Kotwica nie będzie gotowa od razu i musi się rozwiązać.

Aby utworzyć i umieścić punkt kotwiczenia na dachu, wybierz ARAnchorManagerExtensions.resolveAnchorOnRooftopAsync(). Podobnie jak w przypadku punktów kotwiczenia terenu, będziesz mieć też dostęp do PromiseState obietnicy. Następnie możesz sprawdzić wynik obietnicy, aby uzyskać dostęp do 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;
}

Sprawdzanie stanu zobowiązania

Obietnica będzie powiązana z PromiseState (patrz tabela powyżej).

Sprawdzanie stanu kotwicy na dachu w wyniku obietnicy

Wartość RooftopAnchorState należy do operacji asynchronicznej i jest częścią końcowego wyniku obietnicy.

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

Co dalej?