Godot na XREAL AURA: Praktyczny przewodnik po natywnym tworzeniu przestrzennym
W skrócie
Poznaj praktyczny workflow Godota na XREAL AURA: konfiguracja edytora, OpenXR Spatial Containers, dryf kotwicy i najlepsze praktyki.
Twój obecny pipeline budowania XR oznacza podłączenie do komputera, eksport APK, sideloading przez ADB, założenie headsetu, odkrycie literówki i zaczynanie od nowa. XREAL AURA całkowicie eliminuje tę pętlę, a Godot znajduje się w ofercie startowej z pełnym edytorem działającym bezpośrednio na okularach. To zmienia znaczenie słowa „iterować” w tworzeniu przestrzennym.
Ten przewodnik przeprowadzi Cię przez rzeczywisty workflow: uruchomienie edytora na AURA, strukturyzację sceny przestrzennej za pomocą OpenXR Spatial Containers, obsługę modelu passthrough/see-through, który odróżnia okulary optyczne od headsetów VR, oraz pułapki, które dadzą Ci się we znaki przy pierwszym eksporcie.
Dlaczego optyczny see-through zmienia Twoje założenia projektowe
XREAL AURA to pierwsze urządzenie z optycznym see-through na Android XR. To jedno zdanie obala założenia wbudowane w większość tutoriali Godot XR.
W headsetach VR kamera headsetu renderuje wszystko. Użytkownik widzi Twoje środowisko i nic poza nim. W okularach z optycznym see-through użytkownik widzi przez soczewki prawdziwy świat, a renderowana treść jest komponowana na wierzchu. To nie to samo co wideo passthrough na Quest – wideo passthrough przechwytuje rzeczywistość kamerami i wyświetla ją ponownie, co wprowadza opóźnienie i utratę światła. Optyczny see-through ma zerowe opóźnienie kompozytora dla prawdziwego świata.
Praktyczne konsekwencje dla Twojego budżetu renderowania:
- Nie możesz przyciemnić prawdziwego świata. Czerń na przezroczystym wyświetlaczu jest przezroczysta. Nie masz nieprzezroczystego tła, więc UI polegające na kontraście z ciemnymi panelami zawiedzie w jasnym pomieszczeniu.
- Treści wyglądające addytywnie wygrywają. Jasne, emisyjne treści są dobrze widoczne; ciemne, nienasycone znikają. Projektuj paletę z luminancją 2-3x większą niż w VR.
- Pole widzenia jest węższe niż w VR. Treści umieszczone pod skrajnymi kątami wypadają poza obszar wyświetlania. Trzymaj główne cele interakcji w granicach około ±30 stopni od środka.
Jeśli wcześniej wydawałeś VR, przygotuj się na ponowne dostrojenie każdego materiału i każdego panelu UI. Zaplanuj na to pełny dzień na scenę.
Konfiguracja edytora Godot na okularach
Edytor jest dystrybuowany przez Google Play, a nie jako sideloadowany APK. To istotne, bo oznacza, że możesz go aktualizować jak każdą inną aplikację.
Sekwencja konfiguracji:
- Zainstaluj edytor Godot na XREAL AURA ze Sklepu Play.
- Zainstaluj towarzyszącą aplikację środowiska budowania Gradle. Zawiera ona toolchain eksportu Androida, więc nie musisz budować JDK i Android SDK od zera na urządzeniu.
- Zaloguj się na tożsamość dewelopera Androida, jeśli planujesz podpisywać i publikować buildy z urządzenia.
- Uruchom edytor – otwiera się w wielookienkowej przestrzeni roboczej, a nie w pojedynczym płaskim oknie.
Ten czwarty punkt jest najciekawszy. Edytor oferuje funkcje w stylu desktopowym, ale rozmieszczone jako pływające okna w przestrzeni. Możesz trzymać drzewo sceny w jednym wolumenie, a viewport 2D w innym.
Co faktycznie daje Ci workflow na urządzeniu
Szczera odpowiedź: szybka iteracja nad feel, wolniejsza iteracja nad assetami.
Edycja shaderów, poprawianie transformacji węzłów i testowanie mapowań wejścia na docelowym urządzeniu eliminuje cały cykl eksport-test. Cykl ten trwa zwykle 3-8 minut, gdy uwzględnisz czas budowania, transfer i ponowne uruchomienie. Dziesięć iteracji to stracona godzina.
W czym nie pomaga: importowanie dużych atlasów tekstur, długie bakes lightmap czy wszystko, co obciąża CPU. To rób na stacji roboczej. Realistyczny podział to tworzenie assetów na desktopie, a składanie i strojenie sceny na okularach.
Tworzenie treści przestrzennych za pomocą OpenXR Spatial Containers
Wsparcie Godota dla Android XR obejmuje OpenXR Spatial Containers – wolumeny zarządzane przez system, w których aplikacja umieszcza treści przestrzenne. Analogia z samej platformy jest niemal trafna: tradycyjne aplikacje rysują treści 2D w oknach na desktopie; aplikacje przestrzenne rysują treści 3D w kontenerach w pokoju.
Zanim napiszesz kod, warto zrozumieć dwa typy kontenerów:
| Typ kontenera | Najlepszy do | Kompromis |
|---|---|---|
| Volume | Obiektów 3D z prawdziwą głębią, umiejscowienie zablokowane w świecie | System może ograniczyć granice wolumenu |
| Panel | Powierzchni UI, tekstu, gier 2D | Renderowany na stałej płaszczyźnie; wskazówki głębi są płaskie |
Błędem, który popełnia większość deweloperów, jest wybieranie volume dla UI. Tekst w kontenerze volume jest skalowany i przesuwany przez system w sposób, którego nie da się w pełni przewidzieć, a starannie umieszczony widget radaru dryfuje. Umieść UI w kontenerze panel i pozwól systemowi zarządzać pozycjonowaniem.
Praca z API Spatial Container
Godot udostępnia kontenery przestrzenne przez klasy rozszerzeń OpenXR. Dokładne nazwy klas zależą od wersji Godota, więc przed pisaniem kodu produkcyjnego sprawdź listę funkcji silnika dla aktualnych bindingów kontenerów przestrzennych. Poniższy wzorzec odzwierciedla typową strukturę treści XR opartych na kontenerach.
extends Node3D
signal container_created(handle: int)
# Spatial container setup for Android XR.
# Class names are version-dependent; verify against the
# OpenXR extension bindings shipped with your Godot build.
var volume_container: SpatialContainer
var panel_container: SpatialContainer
func _ready() -> void:
var xr_interface: XRInterface = XRServer.find_interface("OpenXR")
if xr_interface == null or not xr_interface.is_initialized():
push_error("OpenXR interface unavailable on this device.")
return
# Volume container for the 3D board.
volume_container = SpatialContainer.new()
volume_container.container_type = SpatialContainer.TYPE_VOLUME
volume_container.extent = Vector3(0.6, 0.4, 0.6) # 60cm x 40cm x 60cm
if volume_container.request_container() != OK:
push_error("Volume container request failed.")
return
# Panel container for the HUD.
panel_container = SpatialContainer.new()
panel_container.container_type = SpatialContainer.TYPE_PANEL
panel_container.extent = Vector3(0.4, 0.4, 0.02)
panel_container.request_container()
add_child(volume_container)
add_child(panel_container)
container_created.emit(volume_container.get_container_handle())
func _process(_delta: float) -> void:
# Containers can be rejected or resized by the system.
if volume_container and not volume_container.is_active():
_handle_container_loss()
func _handle_container_loss() -> void:
push_warning("Volume container lost - repositioning.")
# Never assume the container survives; re-request on loss.
volume_container.request_container()
Krytyczna linia to _handle_container_loss(). Kontenery zarządzane przez system są z definicji zarządzane przez system. Użytkownik odchodzi, asystent przestawia treści lub urządzenie odzyskuje przestrzeń. Jeśli Twoja obsługa wejścia nie przetrwa utraty kontenera, aplikacja zostanie z niewidzialną tablicą i graczem wciskającym przyciski.
Pułapka, na którą wpada prawie każdy: dryf kotwicy
Oto konkretny problem, który będzie Cię kosztować najwięcej czasu na debugowanie.
Umieszczasz tablicę 3D w kontenerze volume. Klikasz Play. Wszystko wygląda dobrze. Zdejmujesz okulary, zakładasz je ponownie dwie minuty później, a tablica jest teraz pół metra w lewo i obrócona o 20 stopni.
Dlaczego? Ponieważ zakotwiczyłeś treść do początku świata, a nie do kontenera. Początek świata na urządzeniu przestrzennym nie jest stabilnym miejscem – jest definiowany względem pozycji startowej sesji. Gdy sesja ponownie się kotwiczy, początek świata się przesuwa.
Rozwiązaniem jest trzymanie każdego elementu sceny jako dziecka transformacji kontenera i nigdy nie odczytywanie ani nie zapisywanie globalnej pozycji dla treści przestrzennych:
# WRONG: assumes world origin is stable
func place_piece(piece: Node3D, board_pos: Vector3) -> void:
piece.global_position = board_pos
# RIGHT: position relative to the container transform
func place_piece(piece: Node3D, board_pos: Vector3) -> void:
piece.position = board_pos # local to container
piece.rotation = Vector3.ZERO
Zrób grepa po projekcie w poszukiwaniu .global_position i .global_transform przed wydaniem. Każde trafienie w treściach przestrzennych to potencjalny bug dryfu. Ta klasa bugów pojawia się też w konwencjonalnym 3D i w pracy multiplayer – błędy kotwicy i własności na replikowanej transformacji dają dokładnie ten sam objaw „obiekt teleportował się dla niektórych klientów”, dlatego traktowanie transformacji jako lokalnych względem kontenera, a nie absolutnych, to nawyk wart przeniesienia do każdego projektu sieciowego w Godocie.
Weryfikacja poprawki
Aby potwierdzić, że kotwiczenie działa poprawnie:
- Uruchom scenę i zanotuj pozycję tablicy.
- Zdejmij urządzenie, odczekaj 60 sekund, wejdź ponownie do aplikacji.
- Tablica powinna pojawić się w tym samym fizycznym miejscu względem pokoju, a nie z tym samym przesunięciem względem tego, gdzie stoisz.
- Powtórz z urządzeniem w innej orientacji – siedząc, potem stojąc.
Jeśli dryfuje, Twoje drzewo treści wciąż ma absolutne referencje. Jeśli skacze, ale po skoku pozostaje spójne, kontener jest przestawiany, a Twoja treść poprawnie za nim podąża – to oczekiwane zachowanie, nie bug.
Obsługa tożsamości gracza i stanu trwałego
Aplikacje przestrzenne na Android XR to aplikacje Androida. Wstrzymują się, wznawiają, użytkownik może mieć na urządzeniu wiele zalogowanych tożsamości, a Twoje dane zapisu żyją w tym samym ekosystemie kont co wszystko inne.
Tryb awarii jest subtelny: gracz gra przestrzennie na okularach, a potem otwiera tę samą grę na telefonie. Jeśli stan zapisu jest lokalny dla urządzenia, ma teraz dwa rozbieżne światy i żadnego sposobu na ich pogodzenie. Naprawienie tego to nie problem renderowania, tylko problem tożsamości konta.
Zrobienie tego dobrze samodzielnie oznacza implementację przepływów logowania, serwerowego magazynu zapisów oraz – części, którą wszyscy lekceważą – obsługi konfliktów, gdy dwa urządzenia zapisują do tego samego slotu. Model odczytu/zapisu świadomy rewizji, w którym klient porównuje wersje i jawnie rozwiązuje konflikty, to jedyna wersja, która przetrwa kontakt z prawdziwymi użytkownikami. Zbudowanie tego od zera to praca na wiele tygodni; horizOn zapewnia przypisany do konta zapis w chmurze z odczytami i zapisami świadomymi rewizji dokładnie w tym przypadku, wraz z uwierzytelnianiem e-mail, anonimowym, Google i Apple, aby ta sama tożsamość gracza działała na okularach i telefonie.
Jakiegokolwiek backendu użyjesz, ustal politykę konfliktów przed wydaniem. Last-write-wins po cichu niszczy postępy. Lepiej zapytać gracza, niż stracić dane.
Najlepsze praktyki wydawania na XREAL AURA
- Projektuj pod kątem światła otoczenia. Przetestuj każdy panel UI na zewnątrz w południe i w przyciemnionym pokoju. Jeśli tekst staje się nieczytelny w którymkolwiek z tych warunków, zwiększ kontrast i dodaj subtelną jasną obwódkę zamiast ciemnego cienia – cienie nic nie dają na przezroczystym wyświetlaczu.
- Trzymaj kontenery małe i możliwe do ponownego żądania. Wolumen 60cm jest łatwiejszy do niezawodnego umieszczenia przez system niż 2m. Zakładaj, że każdy kontener może zostać utracony w dowolnym momencie, i napisz ścieżkę odzyskiwania najpierw, nie na końcu.
- Agresywnie ogranicz budżet renderowania. To okulary, nie desktopowe GPU. Celuj w czas klatki poniżej 11 ms (klasa 90 Hz) z wyłączonym temporal anti-aliasing na rzecz MSAA, które kosztuje mniej przy rozdzielczościach przestrzennych.
- Umieszczaj UI w panelach, a treści w wolumenach. Nie walcz z logiką pozycjonowania systemu w przypadku tekstu. Zarezerwuj wolumeny dla rzeczy z prawdziwą głębią, które gracz ogląda pod różnymi kątami.
- Weryfikuj na urządzeniu przed każdym kamieniem milowym. Edytor na okularach sprawia, że to jest tanie. Wyniki z symulatora nie ujawnią dryfu kotwicy, błędów luminancji ani zachowania przy utracie kontenera.
Kolejny krok
Najważniejszy jest tutaj edytor na urządzeniu. Kompresuje pętlę iteracji przestrzennej z minut do sekund, a to różnica między strojeniem projektu a zgadywaniem.
Zacznij od zainstalowania edytora i towarzyszącej aplikacji Gradle na AURA, a następnie przebuduj mały istniejący projekt jako scenę przestrzenną, zamiast zaczynać od zera – od razu napotkasz problemy z kotwiczeniem i luminancją na treści, którą już rozumiesz. Następnie dodaj kontener volume 3D i panel UI i doprowadź oba do stabilności w cyklu wstrzymania/wznowienia. Gdy to się utrzyma, jesteś gotowy projektować dla platformy, a nie przeciwko niej.
Jeśli trwały stan gracza między urządzeniami jest na Twojej liście, horizOn obsługuje przypisany do konta zapis w chmurze z rozwiązywaniem konfliktów po stronie klienta, dzięki czemu Twoja sesja przestrzenna i sesja na płaskim ekranie pozostają spójne.
Źródło: Gotowy na XREAL AURA