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 świecie rzeczywistym.

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 na dowolnej szerokości geograficznej, długości geograficznej i wysokości.

  2. Punkty kotwiczenia na lądzie:
    Punkty kotwiczenia na lądzie umożliwiają umieszczanie treści tylko za pomocą szerokości i długości geograficznej z wysokością w stosunku do terenu w danym miejscu. Wysokość jest określana względem podłoża lub podłogi zgodnie z danymi 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ść) z wysokością względną względem dachu budynku w tej 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 musi być rozwiązany na serwerze? Nie Tak Tak

Wymagania wstępne

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

Umieszczenie kotwic geoprzestrzennych

Każdy typ kotwic 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 pozycji 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 rotację kwateranionową określoną przez Ziemię na ramkę współrzędnych wschód-góra-południe na pozę AR w ramach 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 ulicy, dołącz treści do budynku za pomocą testu kolizji.
  • Zamiast punktów kotwiczenia WGS84 użyj 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 Kreatora geoprzestrzennego, aby wyświetlać i wzbogacać świat o treści 3D bez konieczności fizycznego przemieszczania się do danej lokalizacji. Pozwala to wizualnie umieszczać w Unity Editorze treści 3D za pomocą Map Google. Szerokość geograficzna, 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 Google Maps, spowoduje powstanie marginesu błędu wynoszącego do kilku metrów.
  • Przejdź do lokalizacji fizycznej

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 wyeliminowanie ewentualnych błędów, 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ść i szerokość geograficzną, aby skopiować je 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. Po wyłączeniu przełącznika Budynki 3D kliknij ikonę szpilki , aby dodać punkt na mapie 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 informacje o szerokości geograficznej, długości geograficznej i wysokości znaku geograficznego 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 lokalizacji fizycznej

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

Pobieranie kwaterniony rotacji

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

Punkty kotwiczenia WGS84

Kotwica WGS84 to rodzaj kotwicy, która umożliwia umieszczanie treści 3D w dowolnej szerokości, długości geograficznej i wysokości. Używa ona pozy i orientacji, aby umieścić obiekt w rzeczywistym świecie. Pozycja składa się z szerokości geograficznej, długości geograficznej i wysokości, 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żdej utworzonej 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 punktów kotwiczenia:

  • Jeśli lokalizacja kotwicy znajduje się fizycznie blisko użytkownika, możesz użyć wysokości podobnej do wysokości urządzenia użytkownika.
  • Po uzyskaniu współrzędnych geograficznych użyj interfejsu Elevation API, aby uzyskać wysokość na podstawie specyfikacji EGM96. Aby porównać wysokość w usługach Mapy Google z wysokością w usługach EGM96, musisz przekonwertować wysokość w usługach Mapy Google do WGS84.GeospatialPose Zapoznaj się z narzędziem GeoidEval, które ma zarówno interfejs wiersza poleceń, jak i interfejs HTML. Interfejs Maps API domyślnie 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>, nie z tagów <LookAt>.
  • Jeśli istniejąca kotwica jest w pobliżu i nie znajdujesz się na stromym zboczu, możesz użyć wysokości z GeospatialPose kamery bez korzystania z innego źródła, takiego jak interfejs Maps API.

Tworzenie kotwicy

Gdy masz już szerokość, długość, wysokość i kwaternion obrotu, użyj atrybutu 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);
}

Kotwice do terenu

Kotwica terenu to rodzaj kotwicy, która umożliwia umieszczanie obiektów AR za pomocą tylko szerokości i długości geograficznej, wykorzystując informacje z VPS do określenia dokładnej wysokości nad poziomem morza.

Zamiast podawać żądaną wysokość, podajesz wysokość nad rzeźbą terenu. Jeśli ustawisz wartość 0, 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 kotwicznego terenu za pomocą nowego interfejsu API asynchronicznego

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

Kotwica nie będzie gotowa od razu i musi zostać rozwiązana. 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 obietnicy

Obietnice będą powiązane z PromiseState.

Stan Opis
Pending Operacja jest nadal w stanie oczekiwania.
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ą ostatecznego wyniku funkcji 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

Rooftop anchors Hero

Dachowe punkty kotwiczenia 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 API asynchronicznego

Kotwica nie będzie gotowa od razu i musi zostać rozwiązana.

Aby utworzyć i umieścić punkt kotwiczenia na dachu, wybierz ARAnchorManagerExtensions.resolveAnchorOnRooftopAsync(). Podobnie jak w przypadku punktów orientacyjnych na mapie, możesz też uzyskać 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ą ostatecznego wyniku funkcji 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?