Starszy inżynier oprogramowania
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.
TrySaveAnchorAsync i ponownie wczytać, używając zserializowanych identyfikatorów GUID.Transkrypcja
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.
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.
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.
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.
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.
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ć?
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.
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.
async void CreateAnchorAsync(ARAnchorManager manager, Pose pose) {
var result = await manager.TryAddAnchorAsync(pose);
if (result.status.IsError()) {
// handle error
return;
}
var anchor = result.value;
}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);
}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;
}async void LoadAnchorAsync(ARAnchorManager manager, SerializableGuid guid) {
var result = await manager.TryLoadAnchorAsync(guid);
if (result.status.IsError()) {
// handle error
return;
}
ARAnchor anchor = result.value;
}void Awake() {
planeManager = GetComponent<ARPlaneManager>();
planeManager.enabled = false;
boundingBoxManager = GetComponent<ARBoundingBoxManager>();
boundingBoxManager.enabled = false;
permissionUtil = GetComponent<AndroidXRPermissionUtil>();
}
void OnEnable() {
StartCoroutine(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;
}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.
}
}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;
}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);
}
}
}// 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.
}
}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.
}
}
}