מאגרים מרחביים מאפשרים לאפליקציה לעבד תוכן OpenXR תלת-ממדי בתוך תיבה תוחמת (bounding box) נפחית תלת-ממדית שמנוהלת על ידי המערכת במצב מרחב מלא, או לעבור בזמן הריצה לחוויה בלתי מוגבלת במסך מלא.
במדריך הזה מוסבר איך להגדיר קונטיינרים מרחביים ולהשתמש בהם בפרויקט.
איך פועלים קונטיינרים מרחביים
כשמפעילים את Spatial Container בהגדרות הפרויקט:
- כל הסצנה הפעילה בתלת-ממד ממוקמת בתוך קונטיינר מרחבי ראשי אחד, שמרכזו נמצא בנקודת המוצא של הסצנה
(0, 0, 0). לא צריך לתייג צומתיNode3Dנפרדים או להקצות אותם כדי למקם אותם בתוך מאגר התגים. - האפליקציה מופעלת במצב "מרחב מלא" מנוהל באמצעות מצב גבולות (
BoundedאוImmersive) ומידות גבולות ראשוניות שמוגדרות בהגדרות הפרויקט. במצב מוגבל, המערכת חותכת באופן אוטומטי כל גיאומטריה תלת-ממדית בסצנה שחורגת מהממדים של התיבה התוחמת. - כברירת מחדל, מערכת Android XR מספקת פקדי חלונות כדי שהמשתמש יוכל לתפוס, להזיז ולשנות את המיקום של הקונטיינר המוגבל במרחב תלת-ממדי, או למזער ולסגור אותו. בזמן הריצה, האפליקציה יכולה לשנות את גודל הקונטיינר, לעבור בין מצב מוגבל (
OpenXRSpatialContainerState.BOUNDED) למצב אימרסיבי במסך מלא (OpenXRSpatialContainerState.IMMERSIVE), ולהגיב לשינויים בגבולות ובמצב באמצעות הסינגלטוןOpenXRSpatialContainerExtension.
דרישות מוקדמות
לפני שמתחילים, צריך לוודא שסביבת הפיתוח ומכשיר היעד עומדים בדרישות הבאות:
- גרסת Godot: Godot 4.8-dev ואילך.
- הגדרת הפרויקט: מבצעים את כל השלבים במדריך להגדרת פרויקט ב-Godot Engine.
- Godot OpenXR Vendors Plugin: מתקינים את גרסה 5.2 ומעלה של Godot OpenXR Vendors Plugin, שמאפשרת תמיכה בתוספים ספציפיים ל-Android XR.
- מכשיר יעד: מכשיר Android XR שתומך ב-Spatial API ברמה 4 ומעלה. בזמן הריצה, קוראים לפונקציה
OpenXRSpatialContainerExtension.is_enabled()כדי לוודא שהתוסף זמין במכשיר.
הפעלת קונטיינרים מרחביים בהגדרות הפרויקט
כדי להפעיל את OpenXR, קונטיינרים מרחביים, הרשאות בתחילת ההפעלה ו-passthrough עם מיזוג אלפא, צריך לשנות את הגדרות הפרויקט:
- פותחים את Project > Project Settings (פרויקט > הגדרות הפרויקט).
- מפעילים את המתג Advanced Settings בפינה הימנית העליונה של החלון הגדרות הפרויקט.
- עוברים אל כללי > XR > הצללות ובוחרים באפשרות מופעל.
- עוברים אל General > XR > OpenXR וקובעים את ההגדרות הבאות:
- בוחרים באפשרות Enabled כדי להפעיל את OpenXR בפרויקט.
- מגדירים את מצב מיזוג הסביבה למיזוג אלפא.
- גם בקטע OpenXR, עוברים לקטע Extensions וקובעים את ההגדרות הבאות:
- בוחרים באפשרות Automatically Request Runtime Permissions (בקשה אוטומטית של הרשאות בתחילת ההפעלה) כדי שהאפליקציה תבקש מהמשתמש באופן אוטומטי בזמן ההפעלה את כל הרשאות ה-XR שהוצהרו במניפסט של Android.
- בסעיף המשנה מאגר מרחבי, בוחרים באפשרות מופעל.
- מגדירים את Bounds Mode (מצב גבולות) ל-Bounded (מוגבל) כדי להפעיל בתיבה תוחמת תלת-ממדית, או ל-Immersive (אימרסיבי) כדי להפעיל במצב אימרסיבי במסך מלא.
- מגדירים את Bounds למידות הראשוניות של הרוחב, הגובה והעומק במטרים, למשל
Vector3(1.0, 1.0, 1.0).
- עוברים אל General > Rendering > Viewport ובוחרים באפשרות Transparent Background.
הגדרת ייצוא ל-Android, הרשאות ומצב מרחב מלא
בשלב הבא, מגדירים את ההרשאות, את מצב התחלת הפעילות ואת ההגדרות הקבועות מראש לייצוא ל-Android, כדי שהאפליקציה תפעל במצב "מרחב מלא" עם קונטיינרים מרחביים מופעלים.
הגדרת הייצוא של Android
- עוברים אל Project > Export... (פרויקט > ייצוא) ובוחרים את ההגדרה הקבועה מראש לייצוא ל-Android.
בקטע Gradle Build, בוחרים באפשרות Use Gradle Build ומגדירים את Min SDK לערך
34או יותר.
בקטע XR Features, מגדירים את XR Mode ל-OpenXR ובוחרים באפשרות Enable AndroidXR Plugin.
בקטע תכונות של Android XR, בוחרים באפשרות שימוש בתכונות ניסיוניות.
הוספת הרשאות להבנת הסביבה כדי לנעול את הרצפה
כדי ליצור ולעבד קונטיינר מרחבי בסיסי, לא צריך הרשאות מסוכנות בתחילת ההפעלה (ו-android.permission.HEAD_TRACKING מתווסף למניפסט באופן אוטומטי כשמפעילים את שימוש בתכונות ניסיוניות). עם זאת, אם האפליקציה משתמשת בתכונות של הבנת סצנה, כמו נעילה ועיגון של מאגר מרחבי לרצפה הפיזית, היא חייבת להצהיר על ההרשאה android.permission.SCENE_UNDERSTANDING_COARSE ולבקש אותה בזמן הריצה.
במאמר הסבר על ההרשאות ב-XR מפורט מידע נוסף על ההרשאות ב-Android XR.
אם האפליקציה משתמשת בנעילת רצפה או בהבנת סצנה, צריך להצהיר על android.permission.SCENE_UNDERSTANDING_COARSE ולבקש אותה:
ב-Project > Export... (פרויקט > ייצוא…), > Android, עוברים אל Permissions > Custom Permissions ומוסיפים את
android.permission.SCENE_UNDERSTANDING_COARSE.כשבוחרים באפשרות Automatically Request Runtime Permissions בקטע Project Settings > General > XR > OpenXR > Extensions, האפליקציה מבקשת את ההרשאה באופן אוטומטי כש-OpenXR מופעל. אם אתם צריכים לבקש את ההרשאה באופן ידני ב-GDScript, צריך להפעיל את
OS.request_permission():if not OS.get_granted_permissions().has("android.permission.SCENE_UNDERSTANDING_COARSE"): OS.request_permission("android.permission.SCENE_UNDERSTANDING_COARSE")
הגדרת מצב "מרחב מלא"
קונטיינרים מרחביים ב-Android XR תומכים רק במצב מרחב מלא (XR_ACTIVITY_START_MODE_FULL_SPACE_MANAGED). ודאו שהפעילות ב-Android מצהירה על XR_ACTIVITY_START_MODE_FULL_SPACE_MANAGED בתבנית ה-build בהתאמה אישית (android/build/AndroidManifest.xml, שמותקנת באמצעות Project > Install Android Build Template...):
<manifest ...>
<application ...>
<property
android:name="android.window.PROPERTY_XR_ACTIVITY_START_MODE"
android:value="XR_ACTIVITY_START_MODE_FULL_SPACE_MANAGED"
tools:replace="android:value" />
...
</application>
</manifest>
עבודה עם קונטיינרים מרחביים ב-GDScript
ה-singleton של OpenXRSpatialContainerExtension והמחלקה OpenXRSpatialContainerState חושפים את התוספים XR_EXT_spatial_container ו-XR_EXT_spatial_container_self_rendering ל-GDScript. בזמן הריצה, משתמשים ב-OpenXRSpatialContainerExtension כדי לבדוק את המצב והגבולות של מאגר המרחב הראשי, להאזין לאותות של המאגר ולבקש מעברים בין מצב BOUNDED (תיבה תוחמת תלת-ממדית) למצב IMMERSIVE (תצוגה לא מוגבלת במסך מלא).
חיבור לאותות של Spatial Container
בודקים את OpenXRSpatialContainerExtension.is_enabled() כדי לוודא שהתוסף Spatial Container נתמך ופעיל במכשיר הנוכחי, ומתחברים לאותות של גבולות ומצב הקונטיינר ב-_ready().
OpenXRSpatialContainerExtension פולט את אותות המצב הבאים לגבי המאגר המרחבי:
-
spatial_container_visibility_changed: נשלח עם(spatial_container, is_visible)כשהקונטיינר מוצג (true) או מוסתר (false). צריך להשהות את האנימציות, האודיו או עדכוני הסימולציה כש-is_visibleהואfalse. -
spatial_container_interactability_changed: מופעל עם(spatial_container, is_interactive)כשהמאגר מקבל (true) או מאבד (false) את המיקוד של קלט המשתמש. הפעלה או השבתה של הדגשות אינטראקטיביות וטיפול בקלט כשהמיקוד משתנה. -
spatial_container_bounds_mode_changed: נשלח עם(spatial_container, bounds_mode)כשהקונטיינר עובר ביןOpenXRSpatialContainerState.BOUNDEDל-OpenXRSpatialContainerState.IMMERSIVE. להחליף בין סביבות ויזואליות (כמו Skybox או Passthrough) ורכיבים אינטראקטיביים ספציפיים למצב.
func _ready() -> void:
if OpenXRSpatialContainerExtension.is_enabled():
OpenXRSpatialContainerExtension.spatial_container_bounds_changed.connect(
_on_bounds_changed
)
OpenXRSpatialContainerExtension.spatial_container_bounds_mode_changed.connect(
_on_bounds_mode_changed
)
OpenXRSpatialContainerExtension.spatial_container_visibility_changed.connect(
_on_visibility_changed
)
OpenXRSpatialContainerExtension.spatial_container_interactability_changed.connect(
_on_interactability_changed
)
func _on_visibility_changed(_rid: RID, is_visible: bool) -> void:
# Pause or resume simulation and audio based on visibility
pass
func _on_interactability_changed(_rid: RID, is_interactive: bool) -> void:
# Enable or disable input handling and focus highlights
pass
התאמת קנה המידה של תוכן תלת-ממדי לגבולות של מאגר התגים
במצב BOUNDED, משנים את קנה המידה של תוכן התלת-ממד באופן אחיד לפי המימד הקטן ביותר של bounds, כדי לשמור על יחס הגובה-רוחב שלו ולהתאים אותו תמיד לצד הקטן ביותר של המאגר. כשעוברים למצב IMMERSIVE, צריך לשחזר את הסצנה לקנה מידה של 1:1:
func _on_bounds_changed(_rid: RID, bounds: Vector3) -> void:
var uniform_scale: float = min(bounds.x, bounds.y, bounds.z)
content_root.scale = Vector3.ONE * uniform_scale
func _on_bounds_mode_changed(
_rid: RID, bounds_mode: OpenXRSpatialContainerState.BoundsMode
) -> void:
if bounds_mode == OpenXRSpatialContainerState.IMMERSIVE:
content_root.scale = Vector3.ONE
מעבר בין מצב מוגבל למצב אימרסיבי
כדי לעבור בין נפח תלת-ממדי מוגבל לבין תצוגה מקיפה במסך מלא, צריך להפעיל את request_main_spatial_container_bounds_mode עם OpenXRSpatialContainerState.BOUNDED או OpenXRSpatialContainerState.IMMERSIVE:
# Request transitioning to immersive mode (or pass BOUNDED to return)
OpenXRSpatialContainerExtension.request_main_spatial_container_bounds_mode(
OpenXRSpatialContainerState.IMMERSIVE
)
עוד באותו הקשר
- פיתוח באמצעות קונטיינרים מרחביים
- הסבר על ההרשאות ל-XR
- הוספת תמיכה ב-Android XR לפרויקט קיים של Godot XR
OpenXR™ והלוגו של OpenXR הם סימנים מסחריים בבעלות The Khronos Group Inc. , והם רשומים כסימנים מסחריים בסין, באיחוד האירופי, ביפן ובבריטניה.