Android XR

Projektowanie treści przestrzennych na Androidzie XR za pomocą Unity

Głośniki

  • Levana Chen

    Inżynier oprogramowania

  • Jennifer Stanton

    Starszy inżynier oprogramowania

Informacje

Informacje o wystąpieniu

Dowiedz się, jak zakotwiczać i utrwalać treści 3D w świecie rzeczywistym za pomocą Unity i Androida XR. Podczas tej sesji omówimy platformę Spatial Entities, Cloud Anchors i interfejsy Geospatial API, pokazując, jak tworzyć aplikacje dopasowane kontekstowo, które zapamiętują fizyczne lokalizacje i synchronizują dane przestrzenne wielu użytkowników między sesjami.

Przeanalizujemy architekturę obiektów przestrzennych i dowiemy się, jak zakotwiczać zasoby cyfrowe w obiektach fizycznych, na powierzchniach i w lokalizacjach geograficznych. Poznasz praktyczne przepływy pracy w Unity do mapowania przestrzeni, zachowywania treści między sesjami i tworzenia wspólnych, opartych na lokalizacji doświadczeń AR/XR.

Podsumowanie

  • AR Foundation udostępnia ujednolicony interfejs API do obsługi skryptów na platformach XR za pomocą rozszerzeń OpenXR. Umożliwia on reprezentowanie i wykonywanie zapytań dotyczących obiektów ze świata rzeczywistego, takich jak płaszczyzny i siatki.
  • Trwałe kotwice stabilizują treści cyfrowe między sesjami i ponownymi uruchomieniami urządzenia. Możesz je zachować za pomocą TrySaveAnchorAsync i ponownie wczytać, używając zserializowanych identyfikatorów GUID.
  • Platforma Spatial Entities zastępuje rozszerzenia śledzenia, aby zapewnić obsługę na wielu platformach i lepszą wydajność śledzenia elementów takich jak ramki ograniczające i znaczniki.
  • Komponenty menedżera powinny być wyłączone do momentu przyznania uprawnień Androida XR. Zapobiega to błędom inicjowania podsystemu spowodowanym ograniczonym dostępem do danych wrażliwych środowiska.
  • Interfejs Geospatial API korzysta z usług ARCore w Google Cloud i systemu VPS, aby umieszczać treści w rzeczywistych lokalizacjach na zewnątrz.

Zasoby

Gemini Notebook

Tematy

  • android-xr
  • jedność
  • ar-foundation
  • openxr
  • spatial-entities
  • reklamy zakotwiczone
  • geospatial-api

Transkrypcja

Pobierz transkrypcję

Wprowadzenie i omówienie AR Foundation

  • OK.

  • Witam wszystkich.

  • To jest kurs „Projektowanie treści przestrzennych na Androida XR za pomocą Unity”.

  • Nazywam się Jennifer Stanton.

  • Pracuję w Unity jako starszy inżynier oprogramowania.

  • Pracuję w zespole ds. funkcji XR, a konkretnie nad AR Foundation i powiązanymi pakietami, które wprowadzają rzeczywistość rozszerzoną i mieszaną do Unity.

  • Nazywam się Levana Chen i pracuję w zespole Google ds. silników gier XR.

  • Nasze zespoły skupiły się na dostarczaniu wtyczek i pakietów, które zapewniają ulepszone funkcje XR i płynną integrację z silnikiem gry.

  • Jednym z największych wyzwań, o jakich wspominają nam klienci, jest to, że obsługa wielu platform XR za pomocą tej samej bazy kodu wymaga dużo pracy.

  • AR Foundation to wysokopoziomowa warstwa interfejsu API rzeczywistości powiększonej w Unity.

  • Możesz kierować reklamy na wiele platform XR bez konieczności wprowadzania poważnych zmian w kodzie i zarządzania wieloma bazami kodu. Otrzymujesz też 1 interfejs API do obsługi skryptów funkcji AR na dowolnej platformie.

  • Dzięki temu możesz skupić się na tworzeniu aplikacji, gry lub środowiska, a Unity zajmie się szczegółami platformy.

  • Jednym ze sposobów, w jaki AR Foundation to osiąga, są rozszerzenia OpenXR.

  • Jest to zestaw otwartych, standardowych interfejsów API zdefiniowanych przez Khronos Group.

  • OpenXR utworzył też elementy przestrzenne.

  • To platforma, która umożliwia treściom cyfrowym reprezentowanie świata fizycznego i interakcję z nim.

  • Encje przestrzenne zapewniają ujednolicony model reprezentowania elementów świata rzeczywistego jako obiektów cyfrowych.

  • Chcę podzielić się z Tobą najnowszymi informacjami o AR Foundation, aby pomóc Ci rozpocząć tworzenie treści XR.

  • Następnie omówię możliwości AR Foundation, dzięki którym Twoje treści cyfrowe mogą wchodzić w interakcje ze światem rzeczywistym.

  • Następnie omówię konfigurację projektu, w tym pakiety i inne zależności, aby można było wdrożyć to rozwiązanie w swoich projektach.

  • Na koniec omówię kilka funkcji unikalnych dla Androida XR.

Najważniejsze funkcje AR Foundation

  • Jednym ze sposobów, w jaki AR Foundation cyfrowo reprezentuje świat rzeczywisty, są płaszczyzny.

  • Są to płaskie powierzchnie w środowisku fizycznym, takie jak podłogi, ściany, sufity, a nawet stoły i kanapy.

  • Siatki to struktury 3D reprezentujące geometrię świata fizycznego.

  • Mamy też sposoby na interakcję z prawdziwym światem, czyli rzutowanie promieni.

  • Określają one, gdzie promień przecina się z treściami cyfrowymi.

  • Można to porównać do wskaźnika laserowego, który dostarcza informacji o tym, gdzie świeci.

  • Mamy też kotwice, które pomagają ustabilizować i przenieść punkt w przestrzeni.

  • W dalszej części prezentacji omówię kotwice bardziej szczegółowo.

  • Wszystkie te 4 funkcje są uważane za funkcje AR Foundation.

  • Jest też kilka innych funkcji, które nie zostały wymienione na tym slajdzie.

  • Płaszczyzny i kotwice są uważane za elementy możliwe do śledzenia, ponieważ rozszerzają klasę ARTrackable, a ich menedżery śledzą aktualizacje ze środowiska wykonawczego.

  • Przejdźmy do samolotów.

  • W przypadku płaszczyzn mamy komponent ARPlane, który umożliwia identyfikację płaskich powierzchni w czasie rzeczywistym.

  • Mają etykiety semantyczne, które można wyszukiwać, aby dowiedzieć się, czy płaszczyzna jest podłogą, stołem, ścianą itp.

  • Płaszczyzny mają też dynamiczne granice, więc gdy użytkownik porusza się w świecie rzeczywistym i widzi więcej powierzchni, granice płaszczyzn dynamicznie się rozszerzają, łączą i udoskonalają w czasie rzeczywistym.

  • Możemy też dołączyć do płaszczyzny kolizor siatki, aby obsługiwać fizykę.

  • Oto przykład wykrywania płaszczyzny.

  • To jest scena rzutowania promieni z przykładowych projektów AR Foundation uruchomiona na urządzeniu z Androidem XR.

  • Wykrywa dynamiczne wielokąty 2D w czasie rzeczywistym.

  • Możesz utworzyć aplikację z tą funkcją, postępując zgodnie z naszym przewodnikiem po konfiguracji projektu lub korzystając z jednego z naszych przykładów lub szablonów.

  • Kolejny element to siatki.

  • Siatki to funkcja AR, która zapewnia siatki 3D otoczenia.

  • Do wygenerowanych siatek możemy dołączyć kolizję siatki, co pozwala na interakcję treści cyfrowych z obiektami w świecie rzeczywistym.

  • Siatki umożliwiają przekonujące zasłanianie obiektów.

  • Dzięki temu obiekt wirtualny może wyglądać, jakby znajdował się za obiektem fizycznym.

  • Jeśli obiekt cyfrowy może poruszać się w przestrzeni, możesz użyć tej samej geometrii, aby znaleźć ścieżkę, która omija obiekty w świecie rzeczywistym.

  • Kolejna metoda to rzutowanie promieni.

  • Rzutowanie promieni rzutuje wirtualne promienie na scenę 3D, aby wyszukać przecięcia, bez konieczności wykonywania skomplikowanych obliczeń.

  • Rzutowany promień może potencjalnie przecinać wiele obiektów 3D w środowisku.

  • Możesz skonfigurować rzutowanie promieni, aby trafiało tylko w określone typy treści cyfrowych.

  • Możesz na przykład skonfigurować go tak, aby nie trafiał w płaszczyzny, a tylko przecinał siatki.

Konfiguracja pakietów i zależności

  • Przyjrzyjmy się teraz odpowiednim pakietom.

  • Wszystkie te pakiety współpracują ze sobą i komunikują się, aby zapewnić pełne wrażenia XR.

  • Jak wspomnieliśmy, AR Foundation obsługuje funkcje takie jak płaszczyzny i kotwice.

  • Wtyczka OpenXR obsługuje natywne interfejsy API na różnych platformach XR, więc warto używać tego pakietu, jeśli urządzenie korzysta z OpenXR.

  • Wtyczkę OpenXR można opcjonalnie sparować z pakietem OpenXR Spatial Entities, aby uzyskać dostęp do rozszerzeń Spatial Entities. Więcej informacji na ten temat znajdziesz poniżej.

  • Jeśli wiesz, że będziesz kierować reklamy na urządzenia z Androidem XR, takie jak gogle XR i okulary XR, potrzebujesz pakietu Unity OpenXR Android XR.

  • Ponieważ wszystko to jest zgodne ze wzorcem wtyczki, wpływ na kod powinien być minimalny.

  • Nie wszystkie funkcje są dostępne we wszystkich pakietach AR Foundation.

  • Jeśli na przykład spojrzysz na tę tabelę, zobaczysz, że siatka nie jest obecnie dostępna w pakiecie Unity OpenXR Spatial Entities.

  • Zarządzanie wtyczkami XR umożliwia zarządzanie funkcjami OpenXR wybranymi w projekcie.

  • Jeśli korzystasz z edytora Unity, kliknij Edytuj, Ustawienia projektu, a następnie Zarządzanie wtyczkami XR na pasku bocznym po lewej stronie.

  • Tutaj znajdziesz funkcje i grupy funkcji OpenXR, dzięki czemu możesz wybrać i usunąć wybór tych funkcji i grup funkcji, które chcesz uwzględnić w kompilacji.

  • Na przykład na tym zrzucie ekranu widzimy wszystkie funkcje, które są dostępne w pakiecie Android XR OpenXR.

  • Możesz je też łączyć z elementami przestrzennymi.

  • Oto okno Menedżera pakietów.

  • Wyróżniliśmy niektóre pakiety, które możesz zobaczyć w typowej konfiguracji projektu XR.

  • Jak widać, mamy AR Foundation, o którym już wspominaliśmy.

  • Mamy też wtyczkę OpenXR.

  • Mamy pakiet Androida XR.

  • Wyróżniłem też kilka innych platform, ponieważ z pewnością możesz utworzyć projekt, który będzie kompilowany na wiele platform.

  • W prawym dolnym rogu znajdują się też inne pakiety.

  • Composition Layers, które działają z urządzeniami OpenXR, Core Utils, bardzo przydatne we wszystkim, co dotyczy XR, oraz XR Hands i XR Interaction Toolkit do obsługi danych wejściowych, co jest bardzo ważne.

  • Następny krok to weryfikacja projektu.

  • Jest to więc część zarządzania wtyczkami XR.

  • Weryfikacja projektu może wykryć zduplikowane funkcje, a także inne problemy w projekcie, które należy rozwiązać, aby go uruchomić.

  • Na tym zrzucie ekranu zaznaczyłem jednak zduplikowane funkcje.

  • Oznacza to, że 2 takie same funkcje, np. kotwice, płaszczyzny i promienie,

  • Użytkownik wybrał opcję uwzględnienia duplikatów tych funkcji z kilku pakietów, a system prosi go o wybranie jednej z nich.

Kotwice lokalne i trwałość

  • To prowadzi nas do kotwic lokalnych i trwałości.

  • Kotwice zapewniają, że treści cyfrowe pozostają w wybranych lokalizacjach w środowisku, niezależnie od zmian stanu śledzenia sesji AR.

  • Platformy AR automatycznie aktualizują pozycje kotwic, aby zapewnić ich spójność. Kotwice to najlepszy sposób na utrzymanie treści na miejscu, gdy oddalasz się od kotwicy, a potem do niej wracasz.

  • A co się stanie, gdy użytkownik zamknie aplikację, uruchomi ją ponownie później i wróci do niej w osobnej sesji?

  • Trwałe kotwice umożliwiają zapisywanie kotwic w sesji AR, a następnie wczytywanie ich w kolejnych sesjach.

  • Są zachowywane przez cały cykl życia aplikacji i po ponownym uruchomieniu urządzenia.

  • Na ilustracji widać przykład trwałych kotwic w projekcie AR Foundation Samples.

  • Przykładowa scena zawiera menu ze wszystkimi obsługiwanymi funkcjami na tej platformie, takimi jak zapisywanie i wczytywanie kotwic.

  • W ten sposób dochodzimy do cyklu życia trwałych kotwic.

  • Najpierw tworzysz kotwicę lokalnie, więc nie jest ona jeszcze nigdzie zapisana, nie jest zapisana w pamięci trwałej, tylko jest kotwicą lokalną.

  • Następnie zapisujesz je w miejscu na dane.

  • Następnie możesz ponownie uruchomić aplikację i wczytać ją z pamięci.

  • Niektóre platformy, w tym Android XR, obsługują też usuwanie lub wyłączanie trwałości kotwic.

  • Dostawca elementów przestrzennych obsługuje automatyczne wczytywanie wszystkich zapisanych kotwic, dzięki czemu nie musisz ręcznie żądać każdej kotwicy według jej identyfikatora.

  • W ustawieniach zarządzania wtyczką XR możesz wybrać opcję automatycznego wczytywania zapisanych kotwic w funkcji Kotwice elementów przestrzennych.

  • Zapisanie kotwicy wymaga tylko kilku linijek kodu.

  • Najpierw zaczynamy w edytorze Unity i upewniamy się, że scena jest gotowa, dodając komponent AR Anchor Manager do obiektu gry XR Origin.

  • Menedżer aktualizuje scenę za pomocą śledzonych kotwic z czasu działania.

  • Przejdźmy teraz do kodu.

  • Aby dodać kotwicę, wystarczy wywołać funkcję TryAddAnchorAsync i podać pozycję, w której chcesz umieścić kotwicę.

    async void CreateAnchorAsync(ARAnchorManager manager, Pose pose) {
        var result = await manager.TryAddAnchorAsync(pose);
        if (result.status.IsError()) {
            // handle error
            return;
        }
        var anchor = result.value;
    }
  • Następnie mamy usuwanie kotwic.

    void RemoveAnchor(ARAnchorManager manager, ARAnchor anchor) {
        var result = manager.TryRemoveAnchor(anchor.trackableId);
        if (result.status.IsError()) {
            // handle error
            return;
        }
    }
    
    void DestroyAnchorComponent(ARAnchor anchor) {
        Destroy(anchor);
    }
  • Podobnie jak w poprzednim przypadku, jest to tylko jedna linijka kodu.

  • Wywołujesz TryRemoveAnchor i przekazujesz identyfikator śledzenia kotwicy.

  • Podczas tworzenia kotwicy został jej przypisany identyfikator, który można śledzić.

  • Następnie mamy TrySaveAnchorAsync.

    async void SaveAnchorAsync(ARAnchorManager manager, ARAnchor anchor) {
        var result = await manager.TrySaveAnchorAsync(anchor);
        if (result.status.IsError()) {
            // handle error
            return;
        }
    
        // Save this value, then return it as an input parameter
        SerializableGuid guid = result.value;
    }
  • Jako dane wejściowe przekazujesz kotwicę AR.

  • Ta funkcja zwraca SerializableGuid, który identyfikuje kotwicę w pamięci trwałej.

  • Możesz później użyć identyfikatora GUID podczas wczytywania kotwicy.

  • I tak dochodzimy do wczytywania kotwic.

    async void LoadAnchorAsync(ARAnchorManager manager, SerializableGuid guid) {
        var result = await manager.TryLoadAnchorAsync(guid);
        if (result.status.IsError()) {
            // handle error
            return;
        }
    
        ARAnchor anchor = result.value;
    }
  • Funkcja, którą należy wywołać, to TryLoadAnchorAsync. Przekaż do niej zserializowany identyfikator GUID z poprzedniego kroku.

  • W wyniku zwróci kotwicę AR.

  • To właściwie wszystko.

  • Te funkcje umożliwiają łatwe zarządzanie zarówno kotwicami lokalnymi, jak i trwałymi.

  • Dlatego śledzenie kotwic jest dość kosztownym zadaniem na większości platform AR.

  • Podczas pracy z kotwicami weź pod uwagę te sprawdzone metody: unikaj tworzenia wielu kotwic bardzo blisko siebie, zastanów się, czy możesz użyć pobliskiej kotwicy zamiast tworzyć kolejną, usuwaj kotwice, gdy już ich nie używasz, i wreszcie, jeśli włączysz inną funkcję AR, aby pomóc w obliczeniu żądanej pozycji kotwicy, zastanów się, czy możesz wyłączyć tę funkcję po pomyślnym utworzeniu kotwicy.

  • Teraz przekażę głos Levanie.

Pakiet SDK Androida XR na Unity

  • Dziękuję, Jennifer.

  • Teraz omówię wkład Google w rozwój Androida XR w Unity.

  • Oprócz wtyczek Unity OpenXR, które Jennifer już przedstawiła, Google udostępnia pakiet Android XR SDK dla Unity z dodatkowymi funkcjami dostępnymi na platformie Android XR.

  • Ten pakiet SDK zawiera wiele funkcji i pakietów, a w tej prezentacji skupimy się na pakiecie rozszerzenia Androida XR dla Unity.

  • Podobnie jak OpenXR Android XR i OpenXR Spatial Entities, pakiet rozszerzenia Android XR dla Unity jest dostawcą OpenXR.

  • Architektura tego pakietu wygląda tak, a poszczególne elementy mogą działać równolegle lub niezależnie.

  • Podobnie jak w przypadku wszystkich innych dostawców OpenXR, pakiet Google jest oparty bezpośrednio na standardowym interfejsie OpenXR.

  • Przedstawiamy tu szereg funkcji, które porównujemy z innymi dostawcami.

  • Dzięki temu łatwiej Ci będzie podjąć decyzję, kiedy i dlaczego wybrać dany typ.

  • Możesz mieć pytanie dotyczące obiektu możliwego do śledzenia i znacznika elementu przestrzennego, które są widoczne w tej tabeli.

  • Warto wspomnieć, że dla osób, które już wcześniej tworzyły aplikacje i funkcje na Androida XR, udostępniliśmy te funkcje za pomocą rozszerzeń, które działają tylko na Androidzie XR.

  • Później, jak wspomniała Jennifer, pracowaliśmy jako otwarta grupa OpenXR, a następnie udostępniliśmy rozszerzenie Spatial Entities Extension po prawej stronie i zapewniliśmy spójne działanie na wielu platformach.

  • Obecnie wycofujemy rozszerzenie śledzenia na rzecz platformy Spatial Entities.

  • Nie tylko dlatego, że jest znacznie wydajniejszy, ale też ze względu na obsługę wielu platform.

Tworzenie z użyciem elementów przestrzennych

  • Przyjrzyjmy się teraz bliżej elementom przestrzennym.

  • Oprócz wspomnianych przez Jennifer płaszczyzn, rzutowania promieni i kotwic, ta funkcja jest też obsługiwana przez dostawców elementów przestrzennych, takich jak znaczniki, które mogą wykrywać i dekodować standardowe kody kreskowe 2D oraz śledzić ich pozycję w przestrzeni 3D, a także rozpoznawać znane grafiki 2D i śledzić je w przestrzeni 3D.

  • Następnie ramka ograniczająca, która identyfikuje obiekt fizyczny, taki jak klawiatura, laptop lub mysz, i śledzi jego ramkę ograniczającą w pozycji 3D.

  • W następnym przykładzie skonfigurujemy funkcję ramki ograniczającej, która jest dostępna w pakiecie rozszerzeń Google.

  • Ten widok jest taki sam dla wszystkich funkcji OpenXR.

  • Wystarczy, że najpierw przełączysz się na platformę Android XR, a następnie włączysz dostawcę OpenXR i wybierzesz funkcję OpenXR, której chcesz użyć do kompilacji. Na przykład tutaj pokazano funkcję ramki ograniczającej elementu przestrzennego. Następnie rozwiąż problemy z walidacją projektu.

  • Pomoże Ci znaleźć wszystkie zależności wymagane przez daną funkcję, a następnie rozwiązać konflikty spowodowane przez wiele funkcji, które współtworzą ten sam podsystem.

  • Czasami, a nawet najczęściej, wystarczy wybrać jedną funkcję, jeśli chcesz użyć np. kotwicy, płaszczyzny lub ramki ograniczającej.

  • Na koniec możesz po prostu utworzyć przykładową scenę lub scenę testową.

  • Aby uzyskać dostęp do obiektu możliwego do śledzenia w czasie działania, możesz po prostu dodać komponent menedżera ramki ograniczającej AR. Jest on podobny do komponentu menedżera kotwicy AR. Następnie możesz uzyskać do niego dostęp za pomocą interfejsu AR Foundation.

  • Możesz też zaimportować przykładową encję przestrzenną dostarczoną przez nasz pakiet rozszerzeń jako szablon, od którego możesz zacząć.

  • Oto główna różnica, gdy używasz funkcji AR Foundation na Androidzie XR.

  • Aby aplikacja mogła lepiej zrozumieć otoczenie użytkownika, zwykle potrzebuje dostępu do poufnych danych dotyczących tego otoczenia.

  • Aby chronić użytkownika, Android XR ogranicza system – dostęp do danych za uprawnieniami.

  • Być może już to znasz, np. standardowe wywołanie uprawnień Androida, takie jak dostęp do aparatu lub lokalizacji.

  • Najlepiej jest wyłączyć komponent menedżera podczas uruchamiania, w edytorze (jak widać po prawej stronie) lub w skrypcie, np. w zdarzeniu Awake.

    void Awake() {
        planeManager = GetComponent<ARPlaneManager>();
        planeManager.enabled = false;
        boundingBoxManager = GetComponent<ARBoundingBoxManager>();
        boundingBoxManager.enabled = false;
        permissionUtil = GetComponent<AndroidXRPermissionUtil>();
    }
    
    void OnEnable() {
        StartCoroutine(WaitForPermissions());
    }
  • Po przyznaniu wszystkich wymaganych uprawnień możesz włączyć menedżera za pomocą skryptu, tak jak robi to tutaj funkcja pomocnicza WaitForPermissions.

    IEnumerator WaitForPermissions() {
        planeManager.enabled = false;
        boundingBoxManager.enabled = false;
    
        yield return new WaitUntil(() =>
            permissionUtil.AllPermissionGranted());
    
        // Enable after granted permissions and
        // restart subsystems.
        planeManager.enabled = true;
        boundingBoxManager.enabled = true;
    
        // Save permission status.
        permissionGranted = true;
    }
  • Dzięki temu unikniesz błędu inicjowania podsystemu spowodowanego niewystarczającymi uprawnieniami.

  • To jest specjalna funkcja.

  • Jennifer opowiedziała o kotwicach w AR Foundation. Aby rozszerzyć możliwości kotwic na Androidzie XR, nasz pakiet zawiera też nową funkcję o nazwie kotwice udostępniane.

  • Ta funkcja odtwarza to, co obecnie obsługuje funkcja kotwic AR Foundation, a także zawiera dodatkowe funkcje, takie jak kotwice geoprzestrzenne.

  • Jak można się domyślić, kotwica jest prawdziwym mostem łączącym świat wirtualny i fizyczny.

  • Jennifer pokazała nam, jak je tworzyć, zapisywać i wczytywać, ale wszystko to działo się w przestrzeni lokalnej, np. w Living Room użytkownika.

  • A co z resztą świata?

  • Jak możemy się nim dzielić?

Geospatial API

  • I tu właśnie wkracza Geospatial API.

  • Umożliwia utworzenie kotwicy geoprzestrzennej na podstawie lokalizacji w świecie rzeczywistym, np. ulubionej księgarni lub miejsca spotkań w dużym parku.

  • Dzięki temu interfejs Geospatial API może zapewnić dokładne śledzenie geopozycyjne za pomocą VPS, czyli systemu wirtualnego pozycjonowania, który działa podobnie jak GPS, ale wykorzystuje dane Street View z zewnątrz, aby zapewnić znacznie dokładniejsze wyniki śledzenia.

  • Niektórzy z Was mogą już znać ten widok, jeśli korzystali wcześniej z funkcji geoprzestrzennej ARCore.

  • Aby uzyskać dostęp do interfejsu Geospatial API na Androidzie XR, musimy najpierw połączyć się z backendem hostowanym na platformie Google Cloud.

  • Ponieważ backend geoprzestrzenny jest obsługiwany przez usługę ARCore w Google Cloud, możesz wykonać dokładnie te same czynności, aby skonfigurować projekt w chmurze Google z dostępem do interfejsu ARCore API.

  • Wszystko to umożliwi korzystanie z funkcji Google Cloud na Androidzie XR, która jest dostępna w naszym pakiecie rozszerzeń.

  • Po włączeniu interfejsu Geospatial API i pobraniu klucza interfejsu API z projektu Google Cloud możesz włączyć tę funkcję i skonfigurować uwierzytelnianie w menu ustawień OpenXR, które jest widoczne tutaj. Możesz też skonfigurować ją ręcznie za pomocą interfejsu API skryptów o nazwie TrySetAuthenticationAsync.

    async Task TrySetAuthentication() {
        googleCloudFeature =
            OpenXRSettings.Instance
                .GetFeature<XRGoogleCloudFeature>();
        var result = await googleCloudFeature
            .TrySetAuthenticationAsync(
                strategy, credential);
        if (result.IsSuccess()) {
            // Ready to use for geospatial tracker.
        } else if (result.IsUnsupported())  {
            // Google Cloud feature is not supported
        } else if (result.IsKeylessError()) {
            // Confirm if keyless has been set up properly.
        } else {
            // Handling other common OpenXR errors.
        }
    }
  • Pamiętaj, że platforma Android XR obsługuje obecnie tylko uwierzytelnianie za pomocą klucza interfejsu API, ale w przyszłości dodamy obsługę innych danych uwierzytelniających.

  • Po uwierzytelnieniu możesz użyć menedżera danych geoprzestrzennych, aby uzyskać dostęp do funkcji geoprzestrzennych.

  • Przed integracją zdecydowanie zalecamy sprawdzenie zasięgu VPS w Mapach Google.

  • Dlatego podczas korzystania z tej funkcji musisz mieć też dostęp do sieci.

  • XR Geospatial Manager działa podobnie do komponentu AR Session udostępnianego przez AR Foundation.

  • Dlatego zawiera właściwość stanu statycznego, która wskazuje obsługę systemu i stan śledzenia modułu śledzenia geoprzestrzennego.

  • Zdarzenie zmiany stanu możesz zarejestrować za pomocą takiego wywołania zwrotnego.

    void OnGeospatialStateChanged(XRGeospatialStateChangedEventArgs eventArgs) {
        bool isInitFailed = eventArgs.CurrState == XRGeospatialState.InitializationFailed;
        if (isInitFailed && XRGeospatialManager.InitializationResult.IsCloudAuthError()) {
            // Handle cloud authentication issues.
        } else if (isInitFailed) {
            // Check XRGeospatialManager.InitializationResult for other common OpenXR errors.
        } else {
            // Iterate runtime state change, and handle accordingly.
        }
    }
    
    private void OnEnable() {
        XRGeospatialManager.OnStateChanged += OnGeospatialStateChanged;
    }
  • Gdy stan geoprzestrzenny zmieni się na „uruchomiony”, możesz używać tej instancji menedżera do wszystkich poniższych funkcji.

  • Najpierw, aby sprawdzić dostępność VPS w danej lokalizacji GPS, używamy interfejsu API lokalizacji Unity, aby uzyskać wartość GPS, a następnie sprawdzamy dostępność VPS.

    async Task CheckVPSAvailability(CancellationToken token) {
        var location = Input.location.lastData;
        try {
            var result = await geospatialManager.TryCheckVPSAvailabilityAsync(
                location.latitude, location.longitude);
            token.ThrowIfCancellationRequested();
            if (result.status.nativeStatusCode == (int)XrResultAndroid.GeospatialCoordinateInvalid) {
                // Invalid coordinates, try with another location.
            } else if (result.status.IsError()) {
                // Handle common OpenXR error: result.status.ToOpenXRStatus()
            }  else if (result.value == XRVPSAvailability.Available)  {
                // You may use this pose to attach geospatial anchors.
                var currentGeospatialPose = new XRGeospatialPose(location);
            }
        }
    }
  • Jest to więc w zasadzie alternatywa, jeśli nie chcesz sprawdzać obsługi VPS na mapie, ale musisz wyjść na zewnątrz, aby sprawdzić rzeczywisty stan GPS.

  • Możesz też przekonwertować pozę Unity na pozę geoprzestrzenną za pomocą TryLocate.

    // Geospatial Pose -> Unity Pose
    var geospatialPose =
        new XRGeospatialPose(Input.location.lastData);
    if (geospatialManager.TryLocate(
            geospatialPose, out XRPoseResult result)) {
        if (result.IsPositionValid ||
            result.IsPositionTracked) {
            transform.position = result.Pose.position;
        }
        if (result.IsRotationValid ||
            result.IsRotationTracked) {
            transform.rotation = result.Pose.rotation;
        }
    }
    // Unity Pose -> Geospatial Pose
    Pose pose = new Pose(
        transform.position, transform.rotation);
    if (geospatialManager.TryLocate(
          pose, out XRGeospatialPoseResult result)) {
        if (result.IsPositionValid ||
            result.IsRotationValid) {
            // You may use for anchor attachment.
        }
    }
  • Następnie, korzystając z wyniku sprawdzenia VPS lub konwersji pozycji, możesz dołączyć kotwicę przestrzenną do danej pozycji geoprzestrzennej lub do znanego typu powierzchni, np. terenu lub dachu.

    async void PlaceAnchor(XRGeospatialPose pose) {
        try {
            Result<ARShareableAnchor> anchorResult;
            XRGeospatialSurfaceType typeToPlace = /* Choose your target type */;
            if (typeToPlace == XRGeospatialSurfaceType.Default) {
                anchorResult = geospatialManager.TryAttachGeospatialAnchor(pose);
            } else {
                pose.Altitude = 0;
                anchorResult = await geospatialManager.TryAttachSurfaceAnchorAsync(typeToPlace, pose);
            }
            if (anchorResult.status.IsSuccess()) {
                // ARShareableAnchorManager will track the anchor and update it.
            } else {
                // Handle OpenXR failures.
            }
        }
    }
  • Gdy połączysz wszystkie te elementy, możesz stworzyć naprawdę magiczne wrażenia przestrzenne, w których świat rzeczywisty jest na pierwszym planie.

  • Dlatego umieszczamy tu strzałkę, która poprowadzi odbiorców do docelowego miejsca w świecie rzeczywistym.

  • OK.

  • Pakiet SDK Androida XR nie jest jedynym pakietem, który udostępniliśmy deweloperom Unity.

  • Pakiet SDK Android XR od Google dla Unity zawiera teraz również pakiet Android XR Interaction Framework i pakiet Android XR Audio.

  • Z przyjemnością rozszerzamy pakiet Android XR SDK o obsługę większej liczby funkcji i dodatkowych encji przestrzennych.

Podsumowanie i zasoby

  • To już koniec sesji.

  • Możesz śledzić harmonogram Unity online, aby zobaczyć, co będzie dalej.

  • Pamiętaj, że na początku przyszłego roku pojawi się Unity 7, czyli nowa generacja Unity.

  • W międzyczasie możesz wypróbować te narzędzia i utworzyć projekt, korzystając z szablonu rzeczywistości mieszanej, lub zapoznać się z przykładowym projektem AR Foundation na naszym GitHubie.

  • Aby dowiedzieć się więcej o przestrzennych elementach i obsłudze pakietu Unity, odwiedź stronę w witrynie dla deweloperów aplikacji na Androida.

  • Dziękuję wszystkim.

  • Nie możemy się doczekać, aby zobaczyć, co uda Ci się stworzyć dzięki AR Foundation i elementom przestrzennym na Androidzie XR.

Kod

Fragmenty kodu

Fragment kodu C# w 10:34 w filmie „Local anchors and persistence”
async void CreateAnchorAsync(ARAnchorManager manager, Pose pose) {
    var result = await manager.TryAddAnchorAsync(pose);
    if (result.status.IsError()) {
        // handle error
        return;
    }
    var anchor = result.value;
}
Fragment kodu C# w 10:43 w filmie „Kotwice lokalne i trwałość”
void RemoveAnchor(ARAnchorManager manager, ARAnchor anchor) {
    var result = manager.TryRemoveAnchor(anchor.trackableId);
    if (result.status.IsError()) {
        // handle error
        return;
    }
}

void DestroyAnchorComponent(ARAnchor anchor) {
    Destroy(anchor);
}
Fragment kodu C# w 11:00 w filmie „Kotwice lokalne i trwałość”
async void SaveAnchorAsync(ARAnchorManager manager, ARAnchor anchor) {
    var result = await manager.TrySaveAnchorAsync(anchor);
    if (result.status.IsError()) {
        // handle error
        return;
    }

    // Save this value, then return it as an input parameter
    SerializableGuid guid = result.value;
}
Fragment kodu C# w 11:17 w filmie „Local anchors and persistence”
async void LoadAnchorAsync(ARAnchorManager manager, SerializableGuid guid) {
    var result = await manager.TryLoadAnchorAsync(guid);
    if (result.status.IsError()) {
        // handle error
        return;
    }

    ARAnchor anchor = result.value;
}
Fragment kodu C# w 16:45 w filmie „Building with spatial entities”
void Awake() {
    planeManager = GetComponent<ARPlaneManager>();
    planeManager.enabled = false;
    boundingBoxManager = GetComponent<ARBoundingBoxManager>();
    boundingBoxManager.enabled = false;
    permissionUtil = GetComponent<AndroidXRPermissionUtil>();
}

void OnEnable() {
    StartCoroutine(WaitForPermissions());
}
Fragment kodu w C# w 16:58 w filmie „Tworzenie z użyciem elementów przestrzennych”
IEnumerator WaitForPermissions() {
    planeManager.enabled = false;
    boundingBoxManager.enabled = false;

    yield return new WaitUntil(() =>
        permissionUtil.AllPermissionGranted());

    // Enable after granted permissions and
    // restart subsystems.
    planeManager.enabled = true;
    boundingBoxManager.enabled = true;

    // Save permission status.
    permissionGranted = true;
}
Fragment kodu C# w 19:12 w filmie „Geospatial API”
async Task TrySetAuthentication() {
    googleCloudFeature =
        OpenXRSettings.Instance
            .GetFeature<XRGoogleCloudFeature>();
    var result = await googleCloudFeature
        .TrySetAuthenticationAsync(
            strategy, credential);
    if (result.IsSuccess()) {
        // Ready to use for geospatial tracker.
    } else if (result.IsUnsupported())  {
        // Google Cloud feature is not supported
    } else if (result.IsKeylessError()) {
        // Confirm if keyless has been set up properly.
    } else {
        // Handling other common OpenXR errors.
    }
}
Fragment kodu w C# w 20:24 w filmie „Geospatial API”
void OnGeospatialStateChanged(XRGeospatialStateChangedEventArgs eventArgs) {
    bool isInitFailed = eventArgs.CurrState == XRGeospatialState.InitializationFailed;
    if (isInitFailed && XRGeospatialManager.InitializationResult.IsCloudAuthError()) {
        // Handle cloud authentication issues.
    } else if (isInitFailed) {
        // Check XRGeospatialManager.InitializationResult for other common OpenXR errors.
    } else {
        // Iterate runtime state change, and handle accordingly.
    }
}

private void OnEnable() {
    XRGeospatialManager.OnStateChanged += OnGeospatialStateChanged;
}
Fragment kodu w C# w 20:38 w filmie „Geospatial API”
async Task CheckVPSAvailability(CancellationToken token) {
    var location = Input.location.lastData;
    try {
        var result = await geospatialManager.TryCheckVPSAvailabilityAsync(
            location.latitude, location.longitude);
        token.ThrowIfCancellationRequested();
        if (result.status.nativeStatusCode == (int)XrResultAndroid.GeospatialCoordinateInvalid) {
            // Invalid coordinates, try with another location.
        } else if (result.status.IsError()) {
            // Handle common OpenXR error: result.status.ToOpenXRStatus()
        }  else if (result.value == XRVPSAvailability.Available)  {
            // You may use this pose to attach geospatial anchors.
            var currentGeospatialPose = new XRGeospatialPose(location);
        }
    }
}
Fragment kodu C# w 21:03 w filmie „Geospatial API”
// Geospatial Pose -> Unity Pose
var geospatialPose =
    new XRGeospatialPose(Input.location.lastData);
if (geospatialManager.TryLocate(
        geospatialPose, out XRPoseResult result)) {
    if (result.IsPositionValid ||
        result.IsPositionTracked) {
        transform.position = result.Pose.position;
    }
    if (result.IsRotationValid ||
        result.IsRotationTracked) {
        transform.rotation = result.Pose.rotation;
    }
}
Fragment kodu C# w filmie „Geospatial API” (21:03)
// Unity Pose -> Geospatial Pose
Pose pose = new Pose(
    transform.position, transform.rotation);
if (geospatialManager.TryLocate(
      pose, out XRGeospatialPoseResult result)) {
    if (result.IsPositionValid ||
        result.IsRotationValid) {
        // You may use for anchor attachment.
    }
}
Fragment kodu w C# w 21:11 w filmie „Geospatial API”
async void PlaceAnchor(XRGeospatialPose pose) {
    try {
        Result<ARShareableAnchor> anchorResult;
        XRGeospatialSurfaceType typeToPlace = /* Choose your target type */;
        if (typeToPlace == XRGeospatialSurfaceType.Default) {
            anchorResult = geospatialManager.TryAttachGeospatialAnchor(pose);
        } else {
            pose.Altitude = 0;
            anchorResult = await geospatialManager.TryAttachSurfaceAnchorAsync(typeToPlace, pose);
        }
        if (anchorResult.status.IsSuccess()) {
            // ARShareableAnchorManager will track the anchor and update it.
        } else {
            // Handle OpenXR failures.
        }
    }
}